Material design is a comprehensive guide for visual, motion, and interaction design across platforms and devices. In this codelab, you'll learn the principles of this design language by building a sample Android app. What you'll learn How to use the Android Design Support Library.

How to use the Vector Drawables.

How to apply material design to your Android app.

The following key material design components and principles:

Themes and colors to create tangible surfaces and print-like design

to create tangible surfaces and print-like design App layout best practices for improved navigability

best practices for improved navigability Animation and touch feedback to express meaningful motion. What you'll need Android Studio version 2.1+ and JDK 8+

Experience developing Android Apps

A test device with Android 4.1+

A USB micro to USB cable. * Android devices running Android 2.3.3 (Gingerbread, API Level 10) or higher may be used, however, some material design effects, such as the ripple effect, will not be visible on devices running on Android 4.4 (KitKat) or before.

Download the sample app You can either download all the sample code to your computer... Download Zip ...or clone the GitHub repository from the command line. $ git clone https://github.com/googlecodelabs/android-design-library.git The android-design-library repository contains many sample projects. This codelab only uses two: android-design-library/1-Base —The starting code that you'll build upon in this codelab.

—The starting code that you'll build upon in this codelab. android-design-library/app—The complete code for the finished sample app. Run the sample app First, let's see what the finished sample app looks like. With the code downloaded, the following instructions describe how to open the completed sample app in Android Studio. Import entire android-design-library package. Select the 1-Base directory from the sample code folder (Quickstart > Import Project... > 1-Base ). Click the Gradle sync button. Enable USB debugging on your Android device. Plug in your Android device and click the Run button. You should see the App home screen appear after a few seconds. Frequently asked questions How do I install Android Studio?

How do I enable USB debugging?

Why doesn't Android Studio see my device?

Material Design Principles covered: Print-like Design Let's jump right into two key features of material design: Themes and Colors! Themes let you apply a consistent tone to an app, and developers can choose between dark or light themes (see Figure 1 and Figure 2). Custom colors can also be defined using theme attributes which are then automatically used by the app for different components e.g colorPrimaryDark for the Status Bar and colorPrimary for the App Bar (see Figure 3 below). Add the Light theme to our app and customize some of the colors in res/values/styles.xml styles.xml <resources> <!-- Base application theme. --> <style name="AppTheme.Base" parent="Theme.AppCompat.Light.NoActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">#3F51B5</item> <!-- Light Indigo --> <item name="colorPrimaryDark">#3949AB</item> <!-- Dark Indigo --> <item name="colorAccent">#00B0FF</item> <!-- Blue --> </style> <style name="AppTheme" parent="AppTheme.Base"></style> </resources> By using attribute parent="Theme.AppCompat.Light.NoActionBar" will remove ActionBar from app. The app should now look like this:

Material Design Principles covered: Tangible Surfaces

Bold Elements

Meaningful Motion In this step you'll create the basic skeleton of an app, which you'll fill in later by adding material design components. Add a toolbar Now you're ready to build on top of the starter project. Add a toolbar and tabs to your app activity_main.xml and MainActivity.java Delete TextView and add Toolbar in activity_main.xml activity_main.xml <RelativeLayout 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:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:layout_scrollFlags="scroll|enterAlways" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" /> </RelativeLayout> MainActivity.java Import android.support.v7.widget.Toolbar at MainActivity.java and add following codes to add Toolbar to Main screen. public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Adding Toolbar to Main screen Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); Add tabs to the toolbar For this codelab we are using CoordinatorLayout as a container for child views such as TabLayout and FloatingActionButton. In activity_main.xml remove RelativeLayout and replace with CoordinatorLayout. In order to use Tabs , we will use TabLayout . First we will create AppBarLayout then we will place ToolbarLayout and TabLayout within AppBarLayout . You can see code samples from below. activity_main.xml <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/main_content" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.design.widget.AppBarLayout android:id="@+id/appbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:layout_scrollFlags="scroll|enterAlways" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" /> <android.support.design.widget.TabLayout android:id="@+id/tabs" android:layout_width="match_parent" android:layout_height="wrap_content" /> </android.support.design.widget.AppBarLayout> </android.support.design.widget.CoordinatorLayout> MainActivity.java Import android.support.design.widget.TabLayout . In MainActivity.java and add following codes within onCreate method to create tabs. protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TabLayout tabs = (TabLayout) findViewById(R.id.tabs); tabs.addTab(tabs.newTab().setText("Tab 1")); tabs.addTab(tabs.newTab().setText("Tab 2")); tabs.addTab(tabs.newTab().setText("Tab 3")); } The app should now look like this: Add Fragment and ViewPager Let's add individual views to the tabs so that when you move between tabs you can have different layouts. Create 3 Fragment java files. ListContentFragment.java , TileContentFragment.java and CardContentFragment.java . Once we created 3 different Fragments files we will now use ViewPager and Adapter to make the content scrollable. In MainActivity.java create a ViewPager variable and Adapter . MainActivity.java protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Adding Toolbar to Main screen Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); // Setting ViewPager for each Tabs ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager); setupViewPager(viewPager); // Set Tabs inside Toolbar TabLayout tabs = (TabLayout) findViewById(R.id.tabs); tabs.setupWithViewPager(viewPager); } // Add Fragments to Tabs private void setupViewPager(ViewPager viewPager) { Adapter adapter = new Adapter(getSupportFragmentManager()); adapter.addFragment(new ListContentFragment(), "List"); adapter.addFragment(new TileContentFragment(), "Tile"); adapter.addFragment(new CardContentFragment(), "Card"); viewPager.setAdapter(adapter); } static class Adapter extends FragmentPagerAdapter { private final List<Fragment> mFragmentList = new ArrayList<>(); private final List<String> mFragmentTitleList = new ArrayList<>(); public Adapter(FragmentManager manager) { super(manager); } @Override public Fragment getItem(int position) { return mFragmentList.get(position); } @Override public int getCount() { return mFragmentList.size(); } public void addFragment(Fragment fragment, String title) { mFragmentList.add(fragment); mFragmentTitleList.add(title); } @Override public CharSequence getPageTitle(int position) { return mFragmentTitleList.get(position); } } In activity_main.xml add a ViewPager element outside of AppBarLayout so that AppBar will stay on top of screen while scrolling the views. activity_main.xml </android.support.design.widget.AppBarLayout> <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> Create a file defining the layout of each view item_list.xml , item_tile.xml and item_card.xml under res/layout/ . Take a look at the individual attributes to see what customizations are available. Your app should now look like this:

Material Design Principles covered: Tangible Surfaces

Cards RecyclerView is a container for displaying large data sets that can be scrolled very efficiently by maintaining a limited number of views. Our data set for this codelab is comprised of empty cards which are pieces of paper that serve as an entry point to more information. Let's add a RecyclerView to our app: Add dependencies to build.gradle to use CardView and RecyclerView. build.gradle dependencies { compile 'com.android.support:appcompat-v7:23.4.0' compile 'com.android.support:design:23.4.0' compile 'com.android.support:cardview-v7:23.4.0' compile 'com.android.support:recyclerview-v7:23.4.0' } Create recycler_view.xml under the res/layout folder. recycler_view.xml <android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/my_recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" android:clipToPadding="false" android:paddingBottom="@dimen/md_keylines" android:paddingTop="@dimen/md_keylines" android:scrollbars="vertical" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> In each fragment, create and customize the RecyclerView . Start by extending RecyclerView.ViewHolder . Replace R.layout.item_tile as appropriate, to match the view used in each fragment.

public static class ViewHolder extends RecyclerView.ViewHolder { public ViewHolder(LayoutInflater inflater, ViewGroup parent) { super(inflater.inflate(R.layout.item_tile, parent, false)); } } In each fragment, create a RecyclerView.Adapter instance, wrapping the ViewHolder that was just created.

public static class ContentAdapter extends RecyclerView.Adapter<ViewHolder> { // Set numbers of List in RecyclerView. private static final int LENGTH = 18; public ContentAdapter() { } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { return new ViewHolder(LayoutInflater.from(parent.getContext()), parent); } @Override public void onBindViewHolder(ViewHolder holder, int position) { // no-op } @Override public int getItemCount() { return LENGTH; } } For each fragment, update onCreateView() to use the new ContentAdapter .



Specifically for TileContentFragment , let's also take a moment to adjust the padding and tell RecyclerView to use a GridLayout — this will make things look nicer, since our tiles will be small.

public class TileContentFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { RecyclerView recyclerView = (RecyclerView) inflater.inflate( R.layout.recycler_view, container, false); ContentAdapter adapter = new ContentAdapter(); recyclerView.setAdapter(adapter); recyclerView.setHasFixedSize(true); // Set padding for Tiles (not needed for Cards/Lists!) int tilePadding = getResources().getDimensionPixelSize(R.dimen.tile_padding); recyclerView.setPadding(tilePadding, tilePadding, tilePadding, tilePadding); recyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 2)); return recyclerView; } If you need help, take a look at TileContentFragment.java , ListContentFragment.java , and CardContentFragment.java . Your app should now look like this: To complete the effect, let's style each view by modifying item_list.xml , item_tile.xml to include an image.



We'll also do the same for item_card.xml , wrapping our RelativeLayout inside a CardView so that we can get the shadows and rounded-corners typical of a card. (On Lollipop or newer devices, shadows is accomplished using Android's native elevation property. On older devices, the support library simulates the effect using drawables.) Your app should now look like this:





Material Design Principles covered: Responsive UI In this step you'll learn how to use VectorDrawable by using Support Library support-vector-drawable. You'll be able to use VectorDrawableCompat back to API 7 device. By using vector assets app only need single vector assets for multiple device screen. Adding config to gradle file Add following new attribute build.gradle // Gradle Plugin 2.0+ android { defaultConfig { vectorDrawables.useSupportLibrary = true } } Import Vector Assets to Android Studio To import vector assets to Android Studio, press CTRL + Enter at drawable directory and choose New -> Vector Asset . For this codelab we will import favorite and share vector assets to style cards . Once you import vector assets, you can now use app:srcCompat instead of android:src to render images within cards by using vector support library. item_card.xml <ImageButton android:id="@+id/share_button" android:layout_width="@dimen/cards_button_width" android:layout_height="@dimen/cards_button_height" android:layout_marginRight="@dimen/md_keylines" app:srcCompat="@drawable/ic_share" android:layout_below="@+id/card_text" android:layout_alignParentRight="true" style="?android:attr/borderlessButtonStyle" android:tint="@color/button_grey" /> Your app should now look like this: You can notice that we have favorite and share icons within card.

Material Design Principles covered: Tangible Surfaces

Bold Elements Add a NavigationDrawer The navigation drawer slides in from the left. It is a common pattern found in Google apps and follows the keylines and metrics for lists. Create a file menu_navigation.xml defining the navigation items under res/menu folder. menu_navigation.xml <menu xmlns:android="http://schemas.android.com/apk/res/android"> <group android:checkableBehavior="single"> <item android:icon="@drawable/ic_home_black_24dp" android:tint="@color/button_grey" android:title="One" /> <item android:icon="@drawable/ic_favorite_black_24dp" android:tint="@color/button_grey" android:title="Two" /> <item android:icon="@drawable/ic_bookmark_border_black_24dp" android:tint="@color/button_grey" android:title="Three" /> </group> </menu> Create a file navheader.xml defining a Navigation Drawer material under the res/layout/ folder.

navheader.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="@dimen/navheader_height" android:background="?attr/colorPrimaryDark" android:orientation="vertical" android:padding="@dimen/md_keylines"> </LinearLayout> In activity_main.xml : Encapsulate all the components within a DrawerLayout which enables interactive drawer views to be pulled out from the edge of the window.

activity_main.xml <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/drawer" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true"> Add a NavigationView outside the CoordinatorLayout . activity_main.xml <android.support.design.widget.NavigationView android:id="@+id/nav_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="true" app:headerLayout="@layout/navheader" app:menu="@menu/menu_navigation" /> In MainActivity.java : Add the following instance variable to the top of MainActivity: private DrawerLayout mDrawerLayout; Add the following code to the onCreate method of MainActivity.java to set the navigation drawer. // Create Navigation drawer and inflate layout NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view); mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer); // Adding menu icon to Toolbar ActionBar supportActionBar = getSupportActionBar(); if (supportActionBar != null) { supportActionBar.setHomeAsUpIndicator(R.drawable.ic_menu_white_24dp); supportActionBar.setDisplayHomeAsUpEnabled(true); } // Set behavior of Navigation drawer navigationView.setNavigationItemSelectedListener( new NavigationView.OnNavigationItemSelectedListener() { // This method will trigger on item Click of navigation menu @Override public boolean onNavigationItemSelected(MenuItem menuItem) { // Set item in checked state menuItem.setChecked(true); // TODO: handle navigation // Closing drawer on item click mDrawerLayout.closeDrawers(); return true; } }); Add mDrawerLayout.openDrawer(GravityCompat.START); to MainActivity.java to make the navigation drawer move when you touch the menu. @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } else if (id == android.R.id.home) { mDrawerLayout.openDrawer(GravityCompat.START); } return super.onOptionsItemSelected(item); } Add a Floating Action Button (FAB) and trigger a SnackBar Floating action buttons are used for a promoted action and are distinguished by a circled icon floating above the UI. Let's create a FAB that triggers a SnackBar which provides lightweight feedback about an operation by showing a brief message.

Design Tips: Not every screen needs a floating action button. A floating action button represents the primary action in an application.

A floating action button represents the primary action in an application. Only one floating action button is recommended per screen to increase its prominence. It should represent only the most common action.

The floating action button doesn't need to be placed in the lower-right corner of the screen. Consider placing it in the upper-left or upper-right, overlapping with the Toolbar .

. A mini-size floating action button can also be used, for situations where you need continuity with other visual elements on screen. For more information: Floating Action Button - Material Design Guidelines In activity_main.xml add a FloatingActionButton to the end of the CoordinatorLayout . In MainActivity.java , add a Listener to the FAB that creates a SnackBar onclick activity_main.xml <android.support.design.widget.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right|bottom" android:layout_marginBottom="@dimen/md_keylines" android:layout_marginRight="@dimen/md_keylines" android:src="@drawable/ic_add_white_24dp" /> MainActivity.java // Adding Floating Action Button to bottom right of main view FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Snackbar.make(v, "Hello Snackbar!", Snackbar.LENGTH_LONG).show(); } }); In values-v21 folder, update styles.xml to create system bar transparent for device running Android 5 and above. styles.xml <resources> <style name="AppTheme" parent="AppTheme.Base"> <item name="android:windowDrawsSystemBarBackgrounds">true</item> <item name="android:statusBarColor">@android:color/transparent</item> </style> </resources> In CardContentFragment.java file add methods when buttons within card pressed shows snackbar. Your app should now look like this: Notice the snack bar pushes the floating action bar out of its way as it's animated onto the screen. This behavior is facilitated by the CoordinatorView in activity_main.xml. As an experiment, try moving the FloatingActionButton outside of the CoordinatorView . (You'll need to define an extra RelativeLayout to make this work.) The snack bar will instead ignore the floating action button's existence while animating itself onto screen! Since animation is an import part of the Material Design experience, make sure to wrap related views with CoordinatorView , and extend CoordinatorLayout.Behavior if any views need to implement a dependent animation.