Search results for

All search results
Best daily deals

Affiliate links on Android Authority may earn us a commission. Learn more.

Build a better UI with the Material Design Components library

Learn how to use the essential Material Design components, including BottomNavigationView, NavigationView, TextInputLayout, CoordinatorLayout and CollapsingToolbarLayout.
By

Published onMay 22, 2017

One of the most common criticisms leveled at Android, is the lack of consistency between applications. Since it’s an open platform, Android gives developers the freedom to bring their creative vision to life – but this isn’t always a good thing from the user’s perspective. If you flick through a few apps on your Android device then chances are you’ll encounter at least a couple of applications that look very different from one another – and potentially very different from the Android system in general!

Material Design is Google’s attempt to provide a more consistent experience for Android users, and the Material Design Components (MDC) library is Google’s latest effort to drive the adoption of Material Design.

MDC is essentially a centralized repository of UI components that you can drop into your Android projects, to give them an instant Material Design look. If this sounds familiar, then it’s because MDC is actually a continuation of the Design Support Library, to the point where it even retains the Design Support Library’s import statements. However, this new library does place more of a focus on modularity, and is managed by a dedicated team of Google UX developers and designers, which means components from the MDC library should always adhere to the latest Material Design principles.

In this article I’m going to show you how to get up and running with the MDC library, by walking you through the process of implementing a range of Material Design components.

By the time you’ve completed this article, you’ll have built several Android applications that feature a BottomNavigationView, NavigationView, and a TextInputLayout and TextInputEditText combo, plus you’ll have created a scrollable app containing a CoordinatorLayout, an AppBarLayout, a CollapsingToolbarLayout, a Floating Action Button (FAB) and a snackbar.

Adding MDC to your project

Throughout this article, we’re going to create a number of apps that demonstrate the various MDC library components in action.

To help keep each example as straightforward as possible, I’m going to be implementing these components across various projects. Everytime you create a new project, you’ll need to add the MDC-Android library as a project dependency, although since the Material Component Library is a continuation of the Design Support Library, this looks exactly the same as adding the Design Support Library.

Before you start, check that you have the latest version of the Support Repository installed by opening the Android SDK Manager, selecting the ‘SDK Tools’ tab and downloading any available ‘Support Repository’ updates.

Next, open your project’s module-level build.gradle file and add the latest version of the MDC/Design Support Library to the dependencies section:

Code
dependencies {
   compile fileTree(dir: 'libs', include: ['*.jar'])

   //Add this line//
   compile 'com.android.support:design:25.3.1'
   androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
       exclude group: 'com.android.support', module: 'support-annotations'
   })
   compile 'com.android.support:appcompat-v7:25.3.1'
   testCompile 'junit:junit:4.12'
   compile 'com.android.support.constraint:constraint-layout:1.0.2'
}

Adding the Material Design Library Components to your project

Many of the MDC components are designed to be used together, and the first app we’re going to build is a perfect example of how you can often deliver a better user experience, by combining multiple MDC library components on a single screen.

In this first section, we’re going to build an app that consists of:

  • A CoordinatorLayout.
  • An AppBarLayout.
  • A CollapsingToolbarLayout (and toolbar).
  • A FAB.
  • A snackbar.

Since CoordinatorLayout, AppBarLayout and CollapsingToolbarLayout are primarily designed to contain other content, we’ll also be implementing some scrollable content, so you can see exactly what impact these MDC containers have on the other Views in your layout.

CoordinatorLayout

As the name suggests, CoordinatorLayout is a layout that helps you coordinate how its child Views interact with one another.
CoordinatorLayouts have a couple of useful attributes that you can apply to its child Views, most notably app:layout_anchor which lets you attach one View to another, and app:layout_insetEdge, which you can use to define inset edges.

In this particular application, we’re using a CoordinatorLayout as it’ll also allow us to implement an AppBarLayout, which in turn means we’ll be able to use a CollapsingToolbarLayout. It also means we’ll be able to create a Floating Action Button (FAB) that’ll slide out of the way automatically whenever this app needs to display a snackbar.

To create a CoordinatorLayout, open your main_activity file and add the following:

Code
<android.support.design.widget.CoordinatorLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:id="@+id/coordinatorLayout">
</android.support.design.widget.CoordinatorLayout>

AppBarLayout

By implementing an AppBarLayout, we can define how all of its child Views respond to scrolling events, via the app:layout_scrollFlags attribute.

Once you’ve applied app:layout_scrollFlags to a View, you can set it to one, or more of the following flags, depending on the scrolling behaviour you want to implement:

  • scroll. The View will scroll in response to scroll events. If you don’t add this flag, then the View will remain pinned in place while the rest of the screen scrolls. If you’re going to use any of the following flags, then you must also implement app:layout_scrollFlags=“scroll.”
  • enterAlways. This View will scroll off the screen with the rest of the scrollable content, however this View will re-appear as soon as the user starts to scroll upwards. This is sometimes known as the ‘Quick View’ pattern.
  • enterAlwaysCollapsed. This View will always enter the screen at its minimum, or “collapsed” height (essentially, the value of its android:minHeight attribute). The View will expand fully once it reaches the end of its scroll range. This flag only works when used in combination with the enterAlways flag and, of course, the scroll flag, so you’ll need to add the following to your View: app:layout_scrollFlags=”scroll|enterAlways|enterAlwaysCollapsed.”
  • exitUntilCollapsed. As the user scrolls upwards, this View will collapse until its minHeight value is met. The View will remain at this height until the user scrolls in the opposite direction.
  • snap. If the View is only partially visible when the user stops scrolling, then it’ll continue scrolling to its closest edge, for example if only the bottom 30% of a View is visible, then it’ll be scrolled completely offscreen.

You implement an AppBarLayout using the following:

Code
<android.support.design.widget.CoordinatorLayout
...
...
...

<android.support.design.widget.AppBarLayout
   android:id="@+id/app_bar_layout"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

</android.support.design.widget.AppBarLayout>

</android.support.design.widget.CoordinatorLayout>

CollapsingToolbarLayout

The next bit of setup we need to complete, is implementing a CollapsingToolbarLayout, which is a wrapper for Android’s Toolbar component.

A CollapsingToolbarLayout allows us to define how our toolbar content should collapse and expand in response to scrolling activity, via the app:layout_collapseMode attribute.

Once you’ve implemented a CollapsingToolbarLayout, you can add the app:layout_collapseMode attribute to any of your toolbar elements, and then set it to one of the following values:

  • Off. No collapsing behaviour.
  • Pin. The View will remain fixed to the screen while the user is scrolling downwards. When the user scrolls upwards, the View will collapse.
  • Parallax. This implements parallax scrolling, where content fades as it collapses. Parallax scrolling is particularly effective when applied to images.

Since the CollapsingToolbarLayout is intended to be wrapped around a Toolbar, let’s add both of these components to our layout:

Code
<android.support.design.widget.CoordinatorLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:id="@+id/coordinatorLayout">

<android.support.design.widget.AppBarLayout
   android:id="@+id/app_bar_layout"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

       //Add our CollapsingToolbarLayout//
       <android.support.design.widget.CollapsingToolbarLayout
          android:id="@+id/collapsing"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"

          // Specify how the Views placed inside the CollapsingToolbarLayout
          // should respond to scrolling events//
          app:layout_scrollFlags="scroll|exitUntilCollapsed"

          // A scrim is a layer of color or a drawable that’ll be applied to the
          // CollapsingToolbarLayout’s content when it’s scrolled offscreen//
          app:contentScrim="?attr/colorPrimary">

         // Add the Toolbar//
         <android.support.v7.widget.Toolbar
             android:id="@+id/toolbar"
             android:layout_width="match_parent"
             android:layout_height="?attr/actionBarSize"
             app:popupTheme="@style/ThemeOverlay.AppCompat.Light"

             // Define your toolbar’s collapsing behaviour//
             app:layout_collapseMode="pin" />
       </android.support.design.widget.CollapsingToolbarLayout>
   </android.support.design.widget.AppBarLayout>

</android.support.design.widget.CoordinatorLayout>

At this point we’ve used multiple components from the MDC library to create a structure that offers us precise control over how all its child Views respond to scrolling events. However, since we haven’t added any content to our toolbar or the main body of our application, we can’t actually see any of this behavior in action. As a result, our app currently doesn’t look all that impressive!

To get a better idea of why we’ve gone to the effort of implementing all these MDC components, let’s add some actual content to our app.

1. NestedScrollView

A NestedScrollView is similar to a ScrollView, but with nested scrolling enabled by default. Although this View isn’t part of the MDC library, since it’s a child of AppBarLayout there is one MDC attribute we need to add to our NestedScrollView.

When you’re using an AppBarLayout, you need to create an association between that AppBarLayout and the View that’s going to be scrolled, which in our case is the NestedScrollView. You create this association using the ‘appbar_scrolling_view_behavior’ string resource that’s included in the MDC library. This string resource maps to the AppBarLayout.ScrollingViewBehavior method, which ensures the AppBarLayout is notified whenever a scroll events occurs on our NestedScrollView.

Code
<android.support.design.widget.CoordinatorLayout
...
...
...

           <android.support.v7.widget.Toolbar
             android:id="@+id/toolbar"
             android:layout_width="match_parent"
             android:layout_height="?attr/actionBarSize"
             app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
             app:layout_collapseMode="pin" />
      </android.support.design.widget.CollapsingToolbarLayout>
   </android.support.design.widget.AppBarLayout>

   //Add our NestedScrollView//
   <android.support.v4.widget.NestedScrollView
       android:id="@+id/scroll"
       android:layout_width="match_parent"
       android:layout_height="match_parent"

   //Create the association between the AppBarLayout and the NestedScrollView//
       app:layout_behavior="@string/appbar_scrolling_view_behavior">

    </android.support.v4.widget.NestedScrollView>

</android.support.design.widget.CoordinatorLayout>

2. ImageView

To see how the content inside our CollapingToolbarLayout expands and collapses in response to scrolling events, let’s add an ImageView to the toolbar. This also gives us the chance to see our scrim in action.

Find an image you want to use as your collapsing toolbar’s header, drag it into your project’s drawable folder, and then add an ImageView to your project:

Code
<android.support.design.widget.CollapsingToolbarLayout
    android:id="@+id/collapsing"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"

    //The CollapsingToolbarLayout’s contents should scroll until it's collapsed//
    app:layout_scrollFlags="scroll|exitUntilCollapsed"
    app:contentScrim="?attr/colorPrimary">

    //Add our image to the collapsing toolbar//
    <ImageView
      android:id="@+id/header_image"
      android:layout_width="match_parent"
      android:layout_height="270dp"
      android:scaleType="centerCrop"
      android:src="@drawable/header"
      app:layout_collapseMode="parallax"/>

3. CardView

To see exactly what impact our scroll flags have on our scrollable content, let’s add a CardView widget to our NestedScrollView, and then create a card with some content.

Open your module-level build.gradle file and add the CardView library as a project dependency:

Code
dependencies {
   compile fileTree(dir: 'libs', include: ['*.jar'])
   compile 'com.android.support:design:25.3.1'

   //Add the CardView support library//
   compile 'com.android.support:cardview-v7:25.3.1'

Open your strings.xml file and define some text that to display as part of our CardView:

Code
<string name="text">This is some text. This is some text. This is some text. </string>

Then, open your layout resource file and add your CardView to the NestedScrollView element:

Code
<android.support.v4.widget.NestedScrollView
   android:id="@+id/scroll"
   android:layout_width="match_parent"
   android:layout_height="match_parent"

   app:layout_behavior="@string/appbar_scrolling_view_behavior">

  //Add the CardView widget//
  <android.support.v7.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/cardview">

   //Define the card’s layout and content//
       <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:padding="26dp"
         android:orientation="vertical">

           <TextView
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:id="@+id/textview"
             android:textSize="20sp"
             android:text="@string/text"
             />

    //Add a Button, which we’ll eventually use to trigger our snackbar//
           <Button
             android:id="@+id/button"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:text="Delete" />

       </LinearLayout>

   </android.support.v7.widget.CardView>

</android.support.v4.widget.NestedScrollView>

Install this project on your Android smartphone or tablet, or a compatible AVD (Android Virtual Device), and try scrolling the layout up and down. As you scroll upwards, the ImageView in the CollapsingToolbarLayout should collapse, and the scrim should appear, creating a “fade out” effect.

That’s the scrolling portion of our sample app finished, however there’s two more MDC elements where our CoordinatorLayout parent can come in particularly useful: snackbars and FABs.

In the next few sections, we’re going to create a FAB and purposefully position it in in the area of the screen where Android displays snackbars by default. We’ll then create a snackbar that’ll appear whenever the user taps the Button we added to our CardView.

While this may seem like a recipe for disaster, since we’re using a CoordinatorLayout as our parent layout, we can give our FAB the ability to slide out of the way automatically, just by adding a single line of code.

Floating Action Button

A FAB is a button that appears to float above your UI, and is intended to help emphasize a screen’s primary action, also sometimes known as the promoted action. If you launch the Gmail app and navigate to your inbox, then you’ll see a FAB that you can use to compose a new message.

It’s recommended that you only ever display one FAB per screen, so you should use a FAB to represent the action the user is most likely to perform whenever they launch this particular Activity. You should also only use FABs for positive actions, such as Create, Share and Favourite, and avoid using FABs for negative or destructive actions like Trash or Archive.

You can create a basic FAB, just by adding the following to your layout resource file:

Code
<android.support.design.widget.FloatingActionButton
      android:id="@+id/fab"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"

      //Specify the drawable resource you want to use as your FAB’s icon//
      android:src="@drawable/ic_search" />

While this is all you need to create a simple FAB, there’s several attributes you can use if you need to customize your FAB’s appearance:

  • Size. By default, all FABs are created at a “normal” 56dpi size, but if you need something smaller than you can create a “mini” fab (40dpi) by adding app:fabSize=”mini” to your code.
  • Border. You can add a border to your FAB using the app:borderWidth attribute, for example app:borderWidth=”20dp.”
  • Elevation. By default, a FAB has a resting elevation of 6dpi and a pressed elevation of 12dpi. You can increase or decrease these values using app:elevation and app:pressedTranslationZ, respectively.
  • Color. Out-of-the-box, a FAB uses your project’s accent color (colorAccent) as its background color. You can apply a different background, using either the app:backgroundTint attribute, or by calling the setBackgroundTintList (ColorStateList tint) method.
  • Ripple colour. You can set the color of the ripple effect when the user presses your FAB, using app:rippleColor. Note that the ripple animation won’t come into affect until you implement an onClicklistener.

We’ll also need an icon to display in our FAB. In the interests of providing a consistent user experience you should use the icons from the Material Icons site wherever possible, so head over to this website, download the icon you want to use and then add it to your project’s drawable folder.

You can then create your FAB. Since this is the last change we’re going to make to this particular project’s activity_main.xml file, let’s review its entire contents:

Code
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/coordinatorLayout">

<android.support.design.widget.AppBarLayout
   android:id="@+id/app_bar_layout"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

   <android.support.design.widget.CollapsingToolbarLayout
       android:id="@+id/collapsing"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       app:layout_scrollFlags="scroll|exitUntilCollapsed"
       app:contentScrim="?attr/colorPrimary">

        <ImageView
          android:id="@+id/header_image"
          android:layout_width="match_parent"
          android:layout_height="270dp"
          android:scaleType="centerCrop"
          android:src="@drawable/header"
          app:layout_collapseMode="parallax"/>

        <android.support.v7.widget.Toolbar
          android:id="@+id/toolbar"
          android:layout_width="match_parent"
          android:layout_height="?attr/actionBarSize"
          app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
          app:layout_collapseMode="pin" />
   </android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>

   <android.support.v4.widget.NestedScrollView
     android:id="@+id/scroll"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     app:layout_behavior="@string/appbar_scrolling_view_behavior">

      <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/cardview">

        <LinearLayout
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:padding="26dp"
          android:orientation="vertical">
           <TextView
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:id="@+id/textview"
             android:textSize="20sp"
             android:text="@string/text"/>

           <Button
             android:id="@+id/button"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:text="Delete" />
        </LinearLayout>

      </android.support.v7.widget.CardView>

     </android.support.v4.widget.NestedScrollView>

   //Add our FAB//
   <android.support.design.widget.FloatingActionButton
     android:id="@+id/fab"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:layout_gravity="bottom|end"
     android:layout_margin="20dp"
     android:src="@drawable/ic_search" />

</android.support.design.widget.CoordinatorLayout>

Snackbar

The final component we’re going to add is a snackbar, which is a popup that can display a single line of text.

Snackbars are typically used to provide the user with instant feedback on an operation they’ve just performed. While this may sound similar to Toasts, there are two areas where snackbars are considerably more powerful than Toasts:

1. Snackbars support actions

Toasts are a one-way dialogue: you can use them to display some information, but the user has no way to respond to this information.

By contrast, snackbars support action buttons, which makes them an ideal way of confirming that an action has just been completed, while giving the user the option to reverse that action. For example you could display a “This email/file/picture has now been deleted” message, with an accompanying “Undo” action button.

A snackbar can only ever display a single action; if you need to display multiple actions then you should use a dialog instead. In addition, you should never add a ‘Dismiss’ or ‘Cancel’ action to a snackbar, as there’s already a number of ways that the user can dismiss a snackbar, so this is just a waste of an action button!

And lastly, snackbars vanish automatically after a period of time has elapsed, or as soon as the user tries to interact with other UI elements. Therefore, you shouldn’t use a snackbar as the sole means of performing an important action – if you do add an action button to your snackbar, then you should always provide the user with an alternate means of performing that action.

2. Snackbars can be dismissed

By default, a snackbar will close after a set period of time has elapsed, when a new snackbar replaces it, or when the user interacts with another onscreen element or navigates to a new Activity. However, if you place a snackbar inside a CoordinatorLayout, then the user can also dismiss a snackbar by swiping if offscreen.

Since we’re adding our snackbar to a CoordinatorLayout, we also have the ability to ensure our FAB shifts out of the way whenever the snackbar appears onscreen. To create this effect, you simply need to pass the CoordinatorLayout to the snackbar’s make() method, for example:

Code
Snackbar mysnackbar = Snackbar
        .make(coordinatorLayout, "Snackbar message", Snackbar.LENGTH_LONG);

mysnackbar.show();

The ‘make’ method takes three parameters:

  • View. Wherever possible, you should pass a CoordinatorLayout to your snackbar as this enables features such as swipe-to-dismiss, while also ensuring any FABs in your layout can move to accommodate your snackbars.
  • Message. This is the text you want to display, and can either be plain text or a string resource. To help ensure your snackbar displays correctly on devices with smaller screens, you should try to keep your snackbar text as succinct as possible.
  • Duration. This can either be LENGTH_SHORT (1500ms), LENGTH_LONG (2750 ms) or LENGTH_INDEFINITE. The latter allows you to create snackbars that remain onscreen until a new snackbar replaces it, or the user either interacts with another onscreen element, moves to a new Activity or drags the snackbar offscreen. The LENGTH_INDEFINITE attribute can be useful if you need some extra assurance that the user will have the chance to see the snackbar, as it won’t vanish automatically after a period of time has elapsed. Alternatively, if you need fine-grained control over how long a snackbar is visible for, then you can specify an exact amount of time using the Snackbar.setDuration(int) function.

Let’s create a snackbar that’ll appear whenever the user taps the button we added to our CardView. To make things more interesting, I’m going to add an action button to this snackbar, using the setAction() method. Tapping this action button will trigger a second snackbar, replacing the first snackbar in the process.

Open your project’s MainActivity file and add the following:

Code
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.Button;
import android.support.design.widget.Snackbar;
import android.view.View;
import android.support.design.widget.CoordinatorLayout;

//You can only use snackbars in Activities that extend AppCompatActivity//
public class MainActivity extends AppCompatActivity {

   private CoordinatorLayout coordinatorLayout;
   private Button button;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_main);

     button = (Button) findViewById(R.id.button);
     coordinatorLayout = (CoordinatorLayout) findViewById(R.id
          .coordinatorLayout);

     button.setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View view) {
         Snackbar snackbar = Snackbar
             .make(coordinatorLayout, "Item deleted", Snackbar.LENGTH_LONG)

             //Add our action//
             .setAction("UNDO", new View.OnClickListener() {
                 @Override
                 public void onClick(View view) {
                     // Tapping the UNDO action will launch a second snackbar//
                     Snackbar snackbarrestored = Snackbar
                          .make(coordinatorLayout, "Item restored!", Snackbar.LENGTH_SHORT);
                     snackbarrestored.show();
                 }
             });
         snackbar.show();
       }
    });
  }
}

Take a look at your FAB and snackbar in action, by installing you updated project on your Android device or AVD, and then tapping the Button to trigger the snackbar. The FAB should animate out of the way automatically.

At this point, you can test another feature that comes courtesy of CoordinatorLayout: swipe-to-dismiss. Drag the snackbar to the right and it should disappear, and the FAB should react by shifting back to its original position.

Trigger the snackbar again, and this time tap the “UNDO” action button. This will trigger a second snackbar, which again you can swipe offscreen by dragging it to the right.

BottomNavigationView

The next MDC component we’re going to look at is BottomNavigationView, which is a standard navigation bar that’s displayed along the bottom of the screen.

A bottom navigation bar is ideal for providing the user with quick and easy access to your app’s most important destinations, although a BottomNavigationView can only support a maximum of five items. If your top-level navigation consists of six or more items, then you should use an alternate navigation method, such as a navigation drawer.

In the interests of keeping our code as straightforward as possible, either create a new layout resource file or, ideally, create a new project. If you do create a new project, then remember to add the MDC library as a project dependency, by opening your module-level build.gradle file and adding the following:

Code
compile 'com.android.support:design:25.3.1'

We’re going to need an icon for every item in our bottom navigation menu, so download three icons from the Material Icons site and then drag them into your project’s drawable folder.

You populate the bottom navigation bar by creating a dedicated menu resource file, where you’ll define each <item> that you want to display in your navigation bar.

If your project doesn’t already contain a ‘menu’ folder, then you’ll need to create one:

  • Control-click your project’s ‘res’ folder and select ‘Android resource directory.’
  • In the window that appears, open the ‘Resource type’ dropdown and select ‘menu.’
  • The ‘Directory name’ should update to ‘menu’ automatically, but if it doesn’t then you should set this field to “menu” manually.
  • Click ‘OK.’

Next, you’ll need to create your menu resource file:

  • Control-click your ‘menu’ directory and select ‘New > Menu resource file.’
  • Enter a name for your menu resource file; I’m going to use ‘bottomnavigationmenu.’
  • Click ‘OK.’

Open the menu resource file and define each item you want to display in your navigation bar:

Code
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
   <item
     android:id="@+id/home"
     android:title="Home"
     android:icon="@drawable/ic_home"/>

   <item
     android:id="@+id/favorite"
     android:title="Favorite"
     android:icon="@drawable/ic_favorite"/>

   <item
     android:id="@+id/search"
     android:title="Search"
     android:icon="@drawable/ic_search" />
</menu>

Next, open the layout resource file where you want to display your BottomNavigationView, and populate it with the contents of your menu resource file:

Code
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   xmlns:design="http://schemas.android.com/apk/res-auto"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:context="com.jessicathornsby.bottomviewnavigation.MainActivity">
   <android.support.design.widget.BottomNavigationView
     android:id="@+id/navigation"
     android:layout_alignParentBottom="true"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     design:menu="@menu/bottomnavigationmenu" />
</RelativeLayout>

 

NavigationView

A NavigationView is a scrollable navigation drawer that can give the user instant access to all the most important locations in your app. This can be particularly useful if your app consists of a large number of screens.

To create a NavigationView, you’ll need to:

  • Create the layout of the NavigationView’s header in a separate layout resource file.
  • Define all the items you want to display in the main body of your NavigationView, in a separate menu resource file.
  • Implement the NavigationView element in your layout resource file.

Each menu item in our NavigationView will consist of a short title and an action, so head over to the Material Icons site and download a selection of icons. I’ll be using ic_info, ic_add, ic_attach, ic_cloud, ic_add_photo, ic_search, and ic_settings, plus I’m going to display the ic_account icon in my navigation header. Drag all the icons you want to use into your project’s res/drawable folder.

To create your navigation header:

  • Control-click your project’s res/layout folder.
  • Select ‘New > Layout resource file.’
  • Give this file a name; I’m going to use ‘nav_header.’
  • Click ‘OK.’

Open this new layout resource file and define the layout you want to use as your navigation drawer’s header:

Code
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   android:layout_width="match_parent"
   android:layout_height="200dp"
   android:background="#0000ff"
   android:padding="10dp"
   android:theme="@style/ThemeOverlay.AppCompat.Dark"
   android:gravity="bottom">

   <ImageView android:id="@+id/imageView"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     app:srcCompat="@drawable/ic_account"/>
   <TextView
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:text="Navigation View Menu"
     android:textStyle="bold"/>
</LinearLayout>

Next, you’ll need to define all the menu items you want to display in your navigation drawer:

  • If your project doesn’t already contain a ‘menu’ folder, then create one by Control-clicking your project’s ‘res’ folder and selecting ‘New > Android resource directory.’
  • Create a menu resource file, by Control-clicking your ‘menu’ directory and selecting ‘New > Menu resource file.’
  • Give it the name ‘Drawer’ and then click ‘OK.’

Open the drawer.xml file and define all your menu items. I’m going to divide my list of menu items into two different groups:

Code
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

   // Define the checkable behaviour for all the items in this group.
   // The possible values are none, all, and single//
   <group android:checkableBehavior="single">

      //Create a new menu item//
      <item
        android:id="@+id/Info"

        //Define its drawable icon//
        android:icon="@drawable/ic_info"

        //Define the text that’ll be displayed in the navigation drawer//
        android:title="Info" />
      <item
        android:id="@+id/add"
        android:icon="@drawable/ic_add"
        android:title="Add" />
      <item
        android:id="@+id/attach"
        android:icon="@drawable/ic_attach"
        android:title="Attach" />
      <item
        android:id="@+id/cloud"
        android:icon="@drawable/ic_cloud"
        android:title="Cloud" />
      <item
        android:id="@+id/photo"
        android:icon="@drawable/ic_add_photo"
        android:title="Add a Photo" />

    //End of this group//
   </group>

      //Create a new group, with the title ‘Search and Settings’//
      <item android:title="Search and Settings">
      <menu>

      <item
        android:id="@+id/search_menu"
        android:icon="@drawable/ic_search"
        android:title="Search" />
 
      <item
        android:id="@+id/settings"
        android:icon="@drawable/ic_settings"
        android:title="Settings" />
      </menu>
      </item>
</menu>

The final step is to open your activity_main.xml file and implement your actual NavigationView element, plus a DrawerLayout parent layout:

Code
<?xml version="1.0" encoding="utf-8"?>

   //Create the DrawerLayout that’ll contain our NavigationView//
   <android.support.v4.widget.DrawerLayout
     android:id="@+id/drawer_layout"
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:fitsSystemWindows="true">
       <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:orientation="vertical">

       // This is where you’d define any UI elements you want to
       // display as part of the main app content//
       </LinearLayout>
       <android.support.design.widget.NavigationView
         android:id="@+id/navigation"
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
         android:layout_gravity="start"

         // Reference the ‘nav_header’ file where you defined the
         // layout of the NavigationView’s header//
         app:headerLayout="@layout/nav_header"

         // Reference the ‘drawer’ menu resource file where you
         // defined all the menu items//
         app:menu="@menu/drawer"/>
   </android.support.v4.widget.DrawerLayout>

Install this app on your Android smartphone, tablet or AVD, and then drag the navigation drawer from the left-hand side of the screen. It should look something like this:

TextInputLayout and TextInputEditText

The final two Material Design components we’re going to look at, are designed to be used together.

The TextInputLayout and TextInputEditText components make a minor, but useful tweak to the android:hint attribute that’s commonly used to display temporary text inside an EditText. Hint text can help the user understand what information they need to enter into an EditText, however as soon as the user selects that EditText and starts typing, that hint text disappears.

While this behavior ensures that the user can actually see what they’re typing, it can present a problem if the user starts entering information into an EditText and then gets distracted. By the time they return to your app, they may have forgotten the contents of the android:hint attribute, and consequently have no idea what they’re supposed to be entering into the EditText.

Admittedly this is a very specific use case, but when it does happen, it can be very frustrating, so you should take steps to ensure this situation never occurs in your Android apps.

The TextInputLayout is a component that you can wrap around an EditText to tweak the default behaviour of the android:hint attribute. Initially, your hint will be displayed inside the EditText as normal, but as soon as the user selects the EditText, the hint will transform into a floating label. This floating label remains visible above the EditText for the entire time that EditText is in focus.

Initially, it was recommended that you wrap the TextInputLayout component around a plain EditText element, however this prevents the user from being able to see the hint text when their device is in Extract mode.

Extract mode, also sometimes known as Full Screen, is the mode that the keyboard editor switches to when you tap on an EditText when you’re in landscape mode. The input method editor (IME) extracts the EditText into a full screen view, at which point your floating hint text is no longer visible.

To make sure the user can see your hint text in Extract mode, Google introduced the TextInputEditText component, which is essentially an EditText with an additional field that makes the hint text visible in Extract mode, although the drawback is that it’ll appear as a regular hint and not as a floating hint.

A “floating” android:hint attribute, as seen in Extract mode.

Let’s take a look at these two UI elements in action. Open your activity_main.xml file, and create two TextInputEditTexts – one that asks the user to enter their password, and another that asks them to enter their email address, and wrap them both in a TextInputLayout.

Code
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   android:orientation="vertical"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:context=".MainActivity">

   <android.support.design.widget.TextInputLayout
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:id="@+id/textinputlayout"
     app:hintTextAppearance="@android:style/TextAppearance.Large">

<android.support.design.widget.TextInputEditText
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:id="@+id/email"
   android:hint="Enter email" />

</android.support.design.widget.TextInputLayout>

<android.support.design.widget.TextInputLayout
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:id="@+id/textinputlayout2"
   app:hintTextAppearance="@android:style/TextAppearance.Large">

<android.support.design.widget.TextInputEditText
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:id="@+id/password"
   android:hint="Enter Password"
   android:layout_below="@id/email” />

  </android.support.design.widget.TextInputLayout>

</LinearLayout>

Install this app on a compatible Android device or AVD. Initially, your TextInputEditTexts will look just like regular EditTexts, but as soon as you select either of them, the hint text will transform into a floating label.

Check that the android:hint attribute is visible in Extract mode by selecting one of the EditTexts and then switching your device to landscape orientation.

Wrapping Up

After completing this article, you know how to a implement a wide range of components from the MDC library in your Android apps, including CoordinatorLayouts, CollapsingToolbarLayouts, TextInputLayouts and TextInputEditTexts.

Will you be using components from the MDC library in your own Android projects?