Android Material Design Support Library Part 1

Introduction

 
Google announced Material Design guidelines for Android apps last year and since then it has been adopted by many application developers. Google only issued guidelines to implement a Material theme. The material theme is available to Lollipop devices and no backward compatibility was provided, developers were dependent on libraries made by other developers. Last month Google released the Android Design Support Library that provides support for a large number of UI design components in a single library. I will be showing you how to use components in that library.
 
This article assumes that you have a basic understanding of Android and have done some development using Android Studio. 
Let's start by creating a new Project with an Activity inside it. It will have an Activity with its respective layout, let's call it MainActivity.java and its layout file activity_main.xml.
My demo app has the target SDK version set to 22 and minimum SDK to 15.
 
Let's just add the design support library to our project first. The library already depends on support library v4 and v7, so you don't need to add them separately. 
Add the following line to your dependencies in your app's build.gradle file. 
  1. dependencies {    
  2.    ….    
  3.    compile 'com.android.support:design:22.2.0'    
  4.    …    
  5. }   
    Then we will add a Drawer (Left Menu) to the main activity that is now a standard in a large number of applications.
    Add the following lines of code to add a drawer to your app. 
     
    1. style.xml: Add these lines to your theme,
    1. <!--   your app branding color for the app bar -->    
    2. <item name="colorPrimary">#512da8</item>    
    3. <!--   darker variant for the status bar and contextual app bars -->    
    4. <item name="colorPrimaryDark">#311b92</item>    
    5. <!--   theme UI controls like checkboxes and text fields -->    
    6. <item name="colorAccent">#7e57c2</item>   
      2. activity_main.xml: Add DrawerLayout as the base layout, then you can define 2 layouts inside it, one for the front layout and the other for the left menu layout. 
      1. <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"    
      2.   xmlns:app="http://schemas.android.com/apk/res-auto"    
      3.   android:id="@+id/drawer_layout"    
      4.   android:layout_height="match_parent"    
      5.   android:layout_width="match_parent">    
      6.       
      7.   <FrameLayout    
      8.       android:id="@+id/content_frame"    
      9.       android:layout_width="match_parent"    
      10.       android:layout_height="match_parent" />    
      11.   <ListView android:id="@+id/left_drawer"    
      12.       android:layout_width="240dp"    
      13.       android:layout_height="match_parent"    
      14.       android:layout_gravity="start"    
      15.       android:choiceMode="singleChoice"    
      16.       android:divider="@android:color/transparent"    
      17.       android:dividerHeight="0dp"    
      18.       android:background="#ffffff"/>    
      19. </android.support.v4.widget.DrawerLayout>   
        3. MainActivity.java: This is the basic code for getting the drawer layout and setting a ActionBarDrawerToggle button, this button opens and closes the drawer. 
        1. public class MainActivity extends AppCompatActivity {    
        2.      
        3. private ActionBarDrawerToggle mDrawerToggle;    
        4. private DrawerLayout mDrawerLayout;    
        5.      
        6. @Override    
        7.   protected void onCreate(Bundle savedInstanceState) {    
        8.       super.onCreate(savedInstanceState);    
        9.       setContentView(R.layout.activity_main);    
        10.       mDrawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout);    
        11.       setTitle("Material Design Example");    
        12.       mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.string.app_name, R.string.app_name);    
        13.       mDrawerLayout.setDrawerListener(mDrawerToggle);    
        14.       getSupportActionBar().setHomeButtonEnabled(true);    
        15.       getSupportActionBar().setDisplayHomeAsUpEnabled(true);    
        16.   }    
        17. }    
        18. @Override    
        19. public boolean onCreateOptionsMenu(Menu menu) {    
        20.   // Inflate the menu; this adds items to the action bar if it is present.    
        21.   getMenuInflater().inflate(R.menu.menu_main, menu);    
        22.   return true;    
        23. }    
        24.      
        25. @Override    
        26. protected void onPostCreate(Bundle savedInstanceState) {    
        27.   super.onPostCreate(savedInstanceState);    
        28.   // Sync the toggle state after onRestoreInstanceState has occurred.    
        29.   mDrawerToggle.syncState();    
        30. }    
        31. @Override    
        32. public void onConfigurationChanged(Configuration newConfig) {    
        33.   super.onConfigurationChanged(newConfig);    
        34.   mDrawerToggle.onConfigurationChanged(newConfig);    
        35. }    
        36. @Override    
        37. public boolean onOptionsItemSelected(MenuItem item) {    
        38.   if (mDrawerToggle.onOptionsItemSelected(item)) {    
        39.       return true;    
        40.   }    
        41.      
        42.   // Handle action bar item clicks here. The action bar will    
        43.   // automatically handle clicks on the Home/Up button, so long    
        44.   // as you specify a parent activity in AndroidManifest.xml.    
        45.   int id = item.getItemId();    
        46.      
        47. //noinspection SimplifiableIfStatement    
        48.   if (id == R.id.action_settings) {    
        49.       return true;    
        50.   }    
        51.      
        52. return super.onOptionsItemSelected(item);    
        53. }   
          At this moment our app looks as in the following,
           
          Now let's start with adding the new components.
           
           
          The first component we will add is the Floating Action Button (FAB). FAB is a small round button usually seen at the bottom-right corner of the screen, although they can be anywhere but need to be at the top of the screen all the time. FAB buttons should be used to promote an action like create, edit and so on. You don't need this button on every screen. For example, create a new mail button in the Gmail app.
           
          There are the following two sizes for the FAB button:
          • Normal size (56dp): For most use cases.
          • Mini size (40dp): Only used if there are similarly sized buttons on the screen.
          You can simply use the OnClickListener to get the click event of this button.
           
          In the main.xml file, add the following code inside the frame to add a FAB button,
          1. <FrameLayout    
          2.   android:id="@+id/content_frame"    
          3.   android:layout_width="match_parent"    
          4.   android:layout_height="match_parent" >    
          5.      
          6.   <android.support.design.widget.FloatingActionButton    
          7.       android:id="@+id/myFloatingActionButton"    
          8.       android:layout_width="wrap_content"    
          9.       android:layout_height="wrap_content"    
          10.       android:layout_gravity="bottom|right"    
          11.       android:src="@drawable/ic_plus"    
          12.       app:fabSize="normal" />    
          13. </FrameLayout>   
            The ic_plus is a small image in the drawable folder. 
             
            This will add a FAB to the bottom-right of the screen. There is a bug in Android 5.0+ devices, the icon sticks to the bottom and Google developers already know this, so the fix is to add a margin of 16dp to API 21+ devices. 
             
            Add in values/dimens.xml
            1. <dimen name="fab_right_margin">0dp</dimen>    
            2. <dimen name="fab_bottom_margin">0dp</dimen> 
            Values-v21/dimens.xml
            1. <dimen name="fab_right_margin">16dp</dimen>    
            2. <dimen name="fab_bottom_margin">16dp</dimen>   
              In activity_main.xml add this,
              1. <android.support.design.widget.FloatingActionButton    
              2.   …    
              3.   android:layout_marginRight="@dimen/fab_right_margin"    
              4.   android:layout_marginBottom="@dimen/fab_bottom_margin"/>   
                This is fixed but there is another bug, the shadow doesn't appear so we will just add a workaround. 
                In activity_main.xml,
                1. <android.support.design.widget.FloatingActionButton    
                2.   …    
                3.   app:borderWidth="0dp"/>   
                  This is how our app looks as of now.
                   
                   
                  Now let's add the second component SnackBar. Snackbar is a small view that shows a message and we can also add an action to it. The snack bar is like a toast that dismisses itself after some time, we can also add an action to it which shows on its right side. We can also swipe dismiss a Snackbar, unlike a toast. The syntax is also similar to a Toast.
                   
                  Let's add it to the click event of FAB that we added earlier,
                  1. private FloatingActionButton mFloatingActionButton;    
                  2. @Override    
                  3. protected void onCreate(Bundle savedInstanceState) {    
                  4. …    
                  5. mFloatingActionButton = (FloatingActionButton)findViewById(R.id.myFloatingActionButton);    
                  6. mFloatingActionButton.setOnClickListener(new View.OnClickListener() {    
                  7.   @Override    
                  8.   public void onClick(View v) {    
                  9.       Snackbar.make(v, "This is a snackbar", Snackbar.LENGTH_SHORT)    
                  10.               .setAction("Ok"new View.OnClickListener() {    
                  11.                   @Override    
                  12.                   public void onClick(View v) {    
                  13.                   }    
                  14.               })    
                  15.               .show();    
                  16.   }    
                  17. });    
                  18.      
                  19. }   
                    This is the result.
                     
                     
                    The snack bar here overlays the FAB. Although this is normal behavior, a FAB and SnackBar can work together. FAB can move up when the SnackBar shows. This can be done by our next component. 
                     
                    Coordinator Layout is a layout that provides an additional level of control over touch events between child views, something that many components in the Design library take advantage of. It will be of greater use later on when we add more components. 
                     
                    We will change the frame layout to CoordinatorLayout in the activity_main.xml file. 
                    1. <android.support.design.widget.CoordinatorLayout    
                    2.   android:id="@+id/content_frame"    
                    3.   android:layout_width="match_parent"    
                    4.   android:layout_height="match_parent" >    
                    5.     <android.support.design.widget.FloatingActionButton    
                    6.       … />    
                    7. </android.support.design.widget.CoordinatorLayout>   
                      This will make the FAB move up with SnackBar. But there is a new bug here, when I swiped the SnackBar, the FAB doesn't come down. We will find a fix for it later.
                      Here is the final result.
                       
                       

                      Summary

                       
                      There are many other components that I will describe in later articles. So please wait until I add more components that are more visually appealing tha the ones we have discussed here.