SnackBar is a feature that allows the user to get some message from the application. It is similar to the well known Toast feature for showing messages to the user. SnackBar is distinguished from the Toast in a way that SnackBar can be placed only on the bottom on the screen, popping up from bottom, with solid color for background. Also, the most interesting part for the SnackBar is that it can have fully functional button for some kind of action.This example will be divided in to three part tutorials, regarding of the java version and usage of ButterKnife library.
In all cases we need to add the android design support library and synchronize the project so the library can be initialized.
1 2 3 |
dependencies { implementation 'com.android.support:design:28.0.0' } |
And here is the layout for the project, containing three different buttons for three different actions of the SnackBar ,depending of the usage:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/rootLayout" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <Button android:id="@+id/simpleSnackBar" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_marginTop="60dp" android:text="Simple snackbar" app:layout_constraintEnd_toEndOf="@id/buttonSnackBar" app:layout_constraintStart_toStartOf="@id/buttonSnackBar" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/buttonSnackBar" android:layout_width="0dip" android:layout_height="wrap_content" android:text="button snackbar" app:layout_constraintEnd_toEndOf="@id/customSnackBar" app:layout_constraintStart_toStartOf="@id/customSnackBar" app:layout_constraintTop_toBottomOf="@id/simpleSnackBar" /> <Button android:id="@+id/customSnackBar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="custom snackbar" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/buttonSnackBar" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingBottom="8dp" android:text="by Viktor Jovanovski" android:textSize="12sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" /> </android.support.constraint.ConstraintLayout> |
We will start first with the plain plain (and most common) Android pattern with Java 7Â of building things:
1 2 3 4 5 6 7 |
ViewGroup rootLayout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); rootLayout = findViewById(R.id.rootLayout); |
The ViewGroup object is our layout that we use in our activity. We can use ViewGroup in every activity, because every layout extends from this class. Ofcourse we add id tag on our root layout. The root layout can be every layout that we want, LinearLayout. RelativeLayout and we can declare this layouts like RelativeLayout rootLayout; LinearLayout rootLayout, and so on. ViewGroup bind all of the layouts and like this the margin of error is minimal, we dont need to track which layout we use.
The layout is declared globaly so we can access it in multiple scopes of methods, but it is instantiated in our @OnCreate overriden method.
This code below is the same thing as above, but using the ButterKnife library:
1 2 3 4 5 6 7 8 9 |
@BindView(R.id.rootLayout) ViewGroup rootLayout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); } |
In @OnCreate method, we are setting up the buttons using the plain Android pattern with Java 7:
1 2 3 |
Button simpleSnackBar = findViewById(R.id.simpleSnackBar); Button buttonSnackBar = findViewById(R.id.buttonSnackBar); Button customSnackBar = findViewById(R.id.customSnackBar); |
and set to them onClickListeners later.
Simple SnackBar implementation:
1 2 3 4 5 6 |
simpleSnackBar.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Snackbar.make(rootLayout, "This is simple SnackBar", Snackbar.LENGTH_SHORT).show(); } }); |
On the SnackBar object we call its static make() method that takes parameters for View layout, String message and int duration. We call here our rootLayout, add appropriate message, and set the duration, again static constant that SnackBar have .LENGTH_ that can be LENGTH_SHORT, LENGTH_LONG and LENGTH_INDEFINITE. At the end of the statement we must call static show() method, otherwise the snackbar wont be shown on the display.
Simple SnackBar with ButterKnife implementation:
1 2 3 4 |
@OnClick({R.id.simpleSnackBar}) public void onSimpleSnackBarClick() { Snackbar.make(rootLayout, "This is simple SnackBar", Snackbar.LENGTH_SHORT).show(); } |
SnackBar with Button implementation plain Android with Java 7:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
Button buttonSnackBar = findViewById(R.id.buttonSnackBar); buttonSnackBar.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Snackbar.make(rootLayout, "This is SnackBar with button", Snackbar.LENGTH_LONG).setAction("Button", new View.OnClickListener() { @Override public void onClick(View view) { // Do your stuff // Automatic dismiss when button clicked // Default color of the button text is your colorAccent Toast.makeText(MainActivity.this, "Button clicked!", Toast.LENGTH_SHORT).show(); } }).show(); } }); |
The difference between the first and the second one is the .setAction() method that add`s button functionality. the setAction() takes CharSequence or simply String, for the text of the button and onClickListener() for when the button is clicked. The onClickListener works the same way as on any button in Android. After that we must call show() method.
SnackBar with Button using ButterKnife implementation:
1 2 3 4 5 |
@OnClick({R.id.buttonSnackBar}) public void onButtonSnackBarClick() { Snackbar.make(rootLayout, "This is SnackBar with button", Snackbar.LENGTH_LONG).setAction("Button" , view -> Toast.makeText(MainActivity.this, "Button clicked!", Toast.LENGTH_SHORT).show()).show(); } |
SnackBar with Button using Java 8, Lambdas & ButterKnife implementation:
1 2 3 4 5 |
@OnClick({R.id.buttonSnackBar}) public void onButtonSnackBarClick() { Snackbar.make(rootLayout, "This is SnackBar with button", Snackbar.LENGTH_LONG).setAction("Button" , view -> Toast.makeText(MainActivity.this, "Button clicked!", Toast.LENGTH_SHORT).show()).show(); } |
Custom SnackBar with Button implementation plain Android with Java 7:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
Button customSnackBar = findViewById(R.id.customSnackBar); customSnackBar.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Snackbar snackbar = Snackbar.make(rootLayout, "This is custom SnackBar", Snackbar.LENGTH_LONG) .setAction("Button", new View.OnClickListener() { @Override public void onClick(View view) { // Do your stuff // Automatic dismiss when button clicked Toast.makeText(MainActivity.this, "Button clicked!", Toast.LENGTH_SHORT).show(); } }); snackbar.setActionTextColor(Color.WHITE); View snackBarView = snackbar.getView(); TextView textView = snackBarView.findViewById(android.support.design.R.id.snackbar_text); textView.setTextColor(Color.YELLOW); snackbar.show(); } }); |
Here we have almost everithing silimilar as previous examples. Here we will set colors of the button text and message text. For the button is straight forward, using setActionTextColor(int) that receives int argument for color. You can use getColor(R.color.yellow) also.
Changing the color for the message text is a little bit different. First we must get the view for the snackbar using .getView on our previously created snackbar assigning to our View. On our view we must find the view for the text by id. That …id.snackbar_text is default for the message. On our view we set the color we want, as any other view, by calling setTextColor(int)
Custom SnackBar using ButterKnife implementation:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
@OnClick({R.id.customSnackBar}) public void onCustomSnackBarClick() { Snackbar snackbar = Snackbar.make(rootLayout, "This is custom SnackBar", Snackbar.LENGTH_LONG) .setAction("Button", new View.OnClickListener() { @Override public void onClick(View view) { // Do your stuff // Automatic dismiss when button clicked Toast.makeText(MainActivity.this, "Button clicked!", Toast.LENGTH_SHORT).show(); } }); snackbar.setActionTextColor(Color.WHITE); View snackBarView = snackbar.getView(); TextView textView = snackBarView.findViewById(android.support.design.R.id.snackbar_text); textView.setTextColor(Color.YELLOW); snackbar.show(); } |
Custom SnackBar using Java 8, Lambdas & ButterKnife implementation:
1 2 3 4 5 6 7 8 9 10 |
@OnClick({R.id.customSnackBar}) public void onCustomSnackBarClick() { Snackbar snackbar = Snackbar.make(rootLayout, "This is custom SnackBar", Snackbar.LENGTH_LONG) .setAction("Button", view -> Toast.makeText(MainActivity.this, "Button clicked!", Toast.LENGTH_SHORT).show()); snackbar.setActionTextColor(Color.WHITE); View snackBarView = snackbar.getView(); TextView textView = snackBarView.findViewById(android.support.design.R.id.snackbar_text); textView.setTextColor(Color.YELLOW); snackbar.show(); } |