Material Components are a set of UI components that helps you build Android apps with Material Design.
In this post, I’ll cover every Material Design component available to us. In addition to components, popular design patterns can be recreated as well. That too, quite easily. For example, the ‘Collapsing App Bar on scroll’ (Read as Flexible Space with Image Pattern).
Moreover, I’ll tell you how to use each Material Component with links to detailed Android tutorials.
Android Bottom Bar (Bottom Navigation View) was officially added in Design Support Library v25. Bottom Bar was first introduced in the Material Design guidelines.
Initially, it was met with some reception. People had polarizing opinions on it. Even I, was on the negative spectrum of thought.The fact that it had existed on iOS for so long, now felt like a poor rip-off for Android.
But irrespective of our opinions, Bottom Navigation is here to stay. It is now officially supported in Android’s Design Support Library, as of version 25.0.0.
A lightweight component that gives feedback to users. It optionally provides an action to users.
Behavior
Snackbars are displayed at the bottom of the screen. It stays there for the specified interval. Or, you can dismiss it by swiping.
However, there arises a confusion with our ‘ol pal, the Toast.
Snackbar VS Toast Confusion
The addition of a Snackbar created ambiguity. When do we use it and when to use Toast?
Its important that we know what to use when. So before moving on to actual code implementation, let’s clear the confusion.
The Difference
Snackbar
Contain a single line of text directly related to the operation performed. They may contain a text action, but no icons.
Lightweight feedback about an operation
Optionally includes a single action
Can optionally stay on-screen permanently, until swiped off screen
Toast
A simple Toast
Primarily used for system messaging. They also display at the bottom of the screen, but may not be swiped off-screen.
System-level messaging
No user action can be performed
Can only stay on screen temporarily. Cannot be swiped
Moving forward
Now that we’re clear about difference between the two, we can start implementing.
First, we’ll look at using a simple usage, right off the bat. Next I’ll tell you how to include a primary action. Then we’ll learn how to style it. Finally, we’ll go over its do’s and don’ts.
Usage
Displaying is relatively simple. In fact, it is similar to how you would write a Toast. We use the class android.support.design.widget.Snackbar .
The view (1st parameter) doesn’t have to be your parent layout. It can be any View.
TIP Ideally, Snackbar works best if your parent layout is a CoordinatorLayout. This ensures that it plays nice with other UI elements (such as FAB). More on that later.
Next, the duration for displaying (3rd parameter), can be any of the following:
LENGTH_INDEFINITE
LENGTH_LONG
LENGTH_SHORT
I hope the duration types above are self-explanatory.
LENGTH_INDEFINITE will show the Snackbar for and indefinite period of time. But you can dismiss it by swiping.
Finally, don’t forget to call Snackbar.show() .
NOTE For Snackbar to work, your Activity must inherit from (extend) AppCompatActivity. Otherwise, consider a third-party alternative.
Adding a Primary Action
As stated in the Material Design spec, we can optionally include an action.
Adding a user action is relatively simple. Simply modify your existing call as follows.
Snackbar
.make(view, "Your message here",
Snackbar.LENGTH_SHORT)
.setAction("YourAction", new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO: Your Action
}
});
.show()
Ideal use-cases for a primary action include:
UNDO – for deleted message, archive, etc
CONNECT – to enable internet if disconnected
RETRY – an action that failed (e.g. API call)
NOTE Do not include an action for DISMISS. This is of no use. Just auto-dismiss your Snackbar by setting a short duration. Or it can simply be swiped away.
Styling
Default properties
The Snackbar class follows the Builder pattern which allows for easy styling.
To style properties such as text colors, you’ll have to fetch the View first.
View snackbarView = snackbar.getView();
Then get the TextView from it.
TextView textView = (TextView) snackbarView.findViewById(
android.support.design.R.id.snackbar_text);
// For multi-line text, limit max line count.
textView.setMaxLines(3);
// Snackbar text color (not action button)
textView.setTextColor(yourColor);
Background color
First, you’ll need a reference. Then apply all your style properties and finally call snackbar.show().
snackbarView.setBackgroundColor(yourColor);
Playing nice with Floating Action Button
Have you seen this behavior before?
The FAB translates up, giving space for the Snackbar to rise from the bottom.
This is the ideal, recommended behavior. Because the last thing we want is the FAB overlap!
So to avoid that, just keep one thing in mind.
Your parent layout (root layout) must be a CoordinatorLayout. It ensures that the correct Behavior is applied to its child Views. In other words, it ensures that UI elements ‘behave’ or ‘coordinate’ correctly.
Here’s an example of how such an XML layout would look like.
Create a CustomSnackbar final class that extends BaseTransientBottomBar.
Next, create an inner, static class ContentViewCallback. Implement the BaseTransientBottomBar.ContentViewCallback interface.
public class CustomSnackbar
extends BaseTransientBottomBar<CustomSnackbar> {
...
private static class ContentViewCallback
implements BaseTransientBottomBar.ContentViewCallback {
// view inflated from custom layout
private View view;
public ContentViewCallback(View view) {
this.view = view;
}
@Override
public void animateContentIn(int delay, int duration) {
// TODO: handle enter animation
}
@Override
public void animateContentOut(int delay, int duration) {
// TODO: handle exit animation
}
}
...
}
Now, our main layout is inflated and taken care of. Next is handling the TextView and action Button.
But keep in mind that a typical Snackbar has this. Moreover, since my custom layout has a Text and Button too, I’m adding functionality to it.
So if you don’t have either of those Views, then skip ahead to point 4.
3. Inflate Custom View
Create a static method make(ViewGroup parent, int duration), similar to the original Snackbar.make() method.
Here, we will inflate our custom layout, using the parent ViewGroup.
public static CustomSnackbar make(ViewGroup parent, int duration) {
// inflate custom layout
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.custom_snackbar, parent, false);
// create with custom view
ContentViewCallback callback= new ContentViewCallback(view);
CustomSnackbar customSnackbar = new CustomSnackbar(parent, view, callback);
customSnackbar.setDuration(duration);
return customSnackbar;
}
4. Display it
Finally, you can display your CustomSnackbar, just like you would with a regular Snackbar.
CustomSnackbar customSnackbar = CustomSnackbar.make(rootView, CustomSnackbar.LENGTH_SHORT);
customSnackbar.setText("Your message here");
customSnackbar.setAction("Action", new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO: handle click here
}
});
customSnackbar.show();
CustomSnackbar.java
Here’s the complete code for the CustomSnackbar class.
public final class CustomSnackbar
extends BaseTransientBottomBar<CustomSnackbar> {
protected CustomSnackbar(@NonNull ViewGroup parent, @NonNull View content, @NonNull ContentViewCallback contentViewCallback) {
super(parent, content, contentViewCallback);
}
public static CustomSnackbar make(ViewGroup parent, int duration) {
// inflate custom layout
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.custom_snackbar, parent, false);
// create with custom view
ContentViewCallback callback= new ContentViewCallback(view);
CustomSnackbar customSnackbar = new CustomSnackbar(parent, view, callback);
customSnackbar.setDuration(duration);
return customSnackbar;
}
private static class ContentViewCallback
implements BaseTransientBottomBar.ContentViewCallback {
// view inflated from custom layout
private View view;
public ContentViewCallback(View view) {this.view = view;}
@Override
public void animateContentIn(int delay, int duration) {// TODO: handle enter animation}
@Override
public void animateContentOut(int delay, int duration) {// TODO: handle exit animation}
}
}
Do’s and Don’ts
Knowing how to use Snackbar is essential. But knowing when to use it is important as well. So before we call this a wrap, let’s look at some do’s and don’ts.
Do
keep the text content short
Allow undoable actions to be undone (delete, archive, etc.)
display feedback results for user actions
style it to match your design
Don’t
include icons
perform core functionality via the action button
display multiple instances
display important system information or errors
overlap or block the FAB (Floating Action Button)
animate or reposition
Conclusion
The Snackbar is comparatively a tiny component in the Material Design spec. Hence it is easily prone to misunderstanding and misuse.
Giving users feedback is important. Effectively using it is key to your app.
Quick Recap
First, we clarified the difference between a Snackbar and Toast. Then we even discussed when to use what.
Next, we looked into using a simple implementation and went onto adding actions. From there, we looked into styling and customization options.
Additionally, we saw that even a custom layout can be used. Finally, we reinforced key guidelines.
Where to from here?
This is just one of the many new additions to Material Design.
The Design Support Library is making life easy for Android Developers to use Material Design. Are you using it?
The DayNight Theme was added to AppCompat with the realease of Support Library v23.2.0. We can reference the theme using Theme.AppCompat.DayNight. DayNight theme allows to switch between light(day) and dark(night) themes, based on the time. Keep in mind that it supports API 14+. Any lower and it defaults to the Light theme. (more…)
Version 23.2 of the Android Support library is a huge update. The Design Support Library made Material Design easy. The new update made it a step easier by adding my personal favorite, Bottom Sheet! In this post, we’ll look into making just that.
SQLite database is one way to store your app’s data locally in Android. In this Android SQLite Database tutorial, I’m here to show you an easier way to it. Using Sugar ORM.
In this tutorial, learn to create an onboarding experience for your apps with Android ViewPager. Similar to the product tour app intro in Google Drive app.
When you launch an app for the first time, you see the onboarding experience. It displays slides, highlighting features about the app with vibrant imagery. Let’s make one for our app, the way Google does for theirs.
Android Marshmallow introduced Chrome Custom Tabs. This allows us to load Web URLs natively from within our app. It leads to a more faster experience, with customizable options making Chrome Custom Tabs more akin to our app’s branding.