Material Snack Bar (Customized )

Behnam Nasehi
6 min readJan 11, 2020

--

Snackbar in android is a new widget introduced with the Material Design library as a replacement of a Toast..

Android Snackbar is a light-weight widget and they are used to show messages at the bottom of the application with swiping enabled. Snackbar android widget may contain an optional action button.

Difference between Toast and Snackbar

  1. A Toast message can be customized and printed anywhere on the screen, but a Snackbar can be only shown at the bottom of the screen.
  2. A Toast message doesn’t have an action button, but Snackbar may have an action button optionally. Though, A Snackbar shouldn’t have more than one action button.
  3. Toast message cannot be off until the time limit finish, but Snackbar can be swiped off before the time limit.
Toast — Snackbar

Display a basic android Snackbar

First of all, you need to add these lines to your dependencies :

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.android.support:design:23.0.1'
}

The Snackbar class provides static make methods to produce a snack bar configured in the desired way. These methods take a View, which will be used to find a suitable ancestor ViewGroup to display the snack bar in, a text string to display (either as a CharSequence or a resource ID), and duration to display the snack bar for (either a duration preset or a time in milliseconds). A suitable ancestor ViewGroup will be either the nearest CoordinatorLayout to the View passed in, or the root DecorView if none could be found.

Available duration presets are:

View rootView= findViewById(R.id.root_view);Snackbar snackbar = Snackbar.make(rootView, "This is our Snackbar Sample !!", Snackbar.LENGTH_LONG);
snackbar.show();

The lines above show you this output :

Now you have a snack bar!
but we already know this, it’s very simple, These are just an introduction…
We definitely want a beautiful and different Snack Bar like Twitter or Gmail App that has border-radius and I choose which color I want to set into the background & etc… :

Make my own Snack Bar

So…
We need to create a class that I named it “SnackBarHelper” and has a constructor and get two parameters as input :

public class SnackBarHelper {public static void configSnackbar(Context context, Snackbar snack) { }    

}

Shadow

For setting elevation to our snack bar we should add these line :

public class SnackBarHelper {public static void configSnackbar(Context context, Snackbar snack) {
ViewCompat.setElevation(snack.getView(), 6f);
}

}

It gets Two parameters, the first one is the view of Snack that we can access to it by the snack bar the second one is the amount of elevation.

Margins

we need to set the margin to our snack bar to look better so we use this function

private static void addMargins(Snackbar snack) {  ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams)           snack.getView().getLayoutParams();
params.setMargins(12, 12, 12, 12); snack.getView().setLayoutParams(params);
}

Set Drawable

In some cases, we want to make our own changes like border-radius background-color and etc..

Step 1: Make The Drawable ( R.drawable.contianer_snackbar )

<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"><solid android:color="#323232" />
<corners android:radius="4dp" />
</shape>

Step 2: The Function

private static void setDrawable (Context context, Snackbar snackbar){  

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { snackbar.getView().setBackground(context.getDrawable(R.drawable.contianer_snackbar));
}

}

Changing The SnackBar Font (Set TypeFace)

I use my custom font that is in my assets folder :

private static void setTypeFace(Context context, Snackbar snackbar) {     TextView tv =   (snackbar.getView()).findViewById(com.google.android.material.R.id.snackbar_text);TextView snackbarActionTextView =      snackbar.getView().findViewById(com.google.android.material.R.id.snackbar_action );Typeface font =      Typeface.createFromAsset(context.getAssets(),"fonts/IranSansRegular.ttf");Typeface bold =Typeface.createFromAsset(context.getAssets(),      "fonts/IranSansMedium.ttf");tv.setTypeface(font);snackbarActionTextView.setTypeface(bold);}

Adding an action

To add an action, use the setAction method on the object returned from make. Actions require both texts to display, and an OnClickListener to handle clicks on the action. Snack bars are automatically dismissed when the action is clicked.

Showing a snack bar with a message and an action would look like this:

Snackbar.make(contextView, R.string.item_removed_message, Snackbar.LENGTH_LONG).setAction(R.string.undo, new OnClickListener() {
@Override
public void onClick(View v) {// Respond to the click, such as by undoing the modification that caused// this message to be displayed})});

Action text color can be customized through the setActionTextColor methods (defaulting to your theme’s accent color).

Action Color

private static void changeActionTextColor(Snackbar snackbar , Context context) {      snackbar.setActionTextColor(context.getResources().getColor(R.color.colorWhite)) 
}

In the end you have to add all these functions to your constructor.

SnackBarHelper.class

public class SnackBarHelper {public static void configSnackbar(Context context, Snackbar snack) {
addMargins(snack);
setRoundBordersBg(context, snack);
setTypeFace(context, snack);
setToRtl(snack);
ViewCompat.setElevation(snack.getView(), 6f);
changeActionTextColor(snack , context);
}
private static void setToRtl(Snackbar snackbar) {
ViewCompat.setLayoutDirection(snackbar.getView(), ViewCompat.LAYOUT_DIRECTION_RTL);
}
private static void changeActionTextColor(Snackbar snackbar , Context context) {
snackbar.setActionTextColor(context.getResources().getColor(R.color.colorWhite));
}
private static void addMargins(Snackbar snack) {
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) snack.getView().getLayoutParams();
params.setMargins(12, 12, 12, Funcations.SnackMargin);
snack.getView().setLayoutParams(params);
}
private static void setRoundBordersBg(Context context, Snackbar snackbar) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
snackbar.getView().setBackground(context.getDrawable(R.drawable.contianer_snackbar));
}
}
private static void setTypeFace(Context context, Snackbar snackbar) {
TextView tv = (snackbar.getView()).findViewById(com.google.android.material.R.id.snackbar_text);
TextView snackbarActionTextView = snackbar.getView().findViewById(com.google.android.material.R.id.snackbar_action );
Typeface font = Typeface.createFromAsset(context.getAssets(), "fonts/IranSansRegular.ttf");
Typeface bold = Typeface.createFromAsset(context.getAssets(), "fonts/IranSansMedium.ttf");
tv.setTypeface(font);
snackbarActionTextView.setTypeface(bold);
}
}

Keyboard Listener

Sometimes the Snackbar hides behind the keyboard and is not visible I wrote this function to solve this problem that when the keyboard opens it will notice the height of the keyboard and store it in a variable Now you have the height of the keyboard and all you have to do is use it as a margin from the bottom :

public static boolean isKeyboardHidden = false;public static int SnackMargin = 12;public static void keyBoardListener(final Activity activity) {
final View activityRootView = activity.findViewById(android.R.id.content);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect rect = new Rect();
activityRootView.getWindowVisibleDisplayFrame(rect);
int heightRoot = activityRootView.getRootView().getHeight();
int heightDiff = heightRoot - rect.bottom;
Log.d("heightRoot", heightRoot + "");
Log.d("heightDiff", heightDiff + "");
if (heightDiff > dpToPx(activity, 200)) {
if (!isKeyboardHidden) {
isKeyboardHidden = true;
SnackMargin = heightDiff + 15;
}
} else if (heightDiff < dpToPx(activity, 200)) {
if (isKeyboardHidden) {
isKeyboardHidden = false;
SnackMargin = 12;
}
}
}
});
}

To use this function you have to call it in any activity you want to show snack bar and use the “snackMargin ” variable for margin from the bottom so I change my margin function that I wrote it to this :

private static void addMargins(Snackbar snack) {ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams)           snack.getView().getLayoutParams();
params.setMargins(12, 12, 12, snackMargin);//it will set margin to bottom
snack.getView().setLayoutParams(params);
}

in my activity for showing the snack bar I use this :

Snackbar snack = Snackbar.make(       activity.findViewById(android.R.id.content),message,      Snackbar.LENGTH_LONG);
SnackBarHelper.configSnackbar(activity, snack);
snack.show();

Now You Have This :

Thank You ! ❤

The situation is very bad here! Yeah, I mean Iran …
People are all sad, so am I
But the world is still beautiful :)

IG: www.instagram.com/behnamnasehi
Gmail: behnammnasehi@gmail.com
Telegram: @Behnamnasehii

--

--