360andev yash prabhu share fb2

A Practical Guide to Material Design for Android Developers

Are you a developer who has heard of Material Design but not sure where to get started? Are you envious of apps like Google Play, YouTube, or Gmail that use fancy animations, beautiful colors, and papercraft effectively? This talk will bridge the gap between Google’s Material design documentation and the Android developer documentation to help you build apps with engaging user experience.

In this 360AnDev talk, you will learn how to:

  • Implement the basics of standard UI elements that are used across most apps like Navigation Drawer, Floating Action Button, Tabs, Grids, CardView, RecyclerView and Coordinator Layout.
  • Use the AppCompat library and Design Support library to implement Material design going all the way back to Android Eclair (2.1).

This talk is for Android developers who are interested in utilizing material design principles in their current or upcoming Android apps. The sample code is available on GitHub @yprabhu.


Introduction (0:00)

First, I want to establish why what we are going to cover is important for you. Recently at my work, we’ve been re-writing the DramaFever app, and it’s a huge project. We wanted to follow a limited design guideline. Our designers wanted particular things, and the developers weren’t sure what we could give them.

This talk came from the experience of re-writing an app to follow material design guidelines. I also noticed that there’s a gap between the material design documentation on the design side and the development side. I wanted to bring both together.

Also, there are a ton of cool apps out there doing material design. When you look at it for the first time, you’re like, “How can I do this?” It seems very complicated. I’m trying to break that down for you. It’s simple once you know that it’s all done in XML.

What is material design? (1:26)

What is material design? Material design is a visual design language; it’s a guide that Google came up with. I think it was introduced in Google I/O 2014 as part of the Lollipop release. It’s the usage of a lot of bold colors, imagery, and typography. It follows a lot of print design guidelines. Also, it is not just for Android; it’s for Android, iOS, and web. For this post, I’m only focusing on Android.

A brief history of mobile design evolution. When the iPhone first came out in 2007, the design guidelines they followed was what they call skeuomorphism, which mimics the physical world. If you look at the iBooks app, you can see that the books look like they’re on an actual book shelf.

Then you have the Windows Phone which has the flat design, and all the UI elements are on one single plane.

And finally you have the material design, which looks like flat design, but it has shadows and elevation and a bunch of other things going for it.

Now the con with flat design was that you weren’t really sure if these UI elements were clickable. But with material design, when you touch something, it raises to your touch. You also see a bit of shadow underneath. You know that these are UI elements that will respond to you as an interaction. The design guidelines are meant to be subtle, but the user knows what to do.

For the rest of the talk I’m going to focus on four parts:

  • Style
  • Layout
  • Animation
  • Components.

We’ll start off with style.

Style (3:03)

I’m going to focus on:

  • Color
  • Theme
  • Typography
  • Imagery

Style - Color

Color is a very important aspect of material design. Your color identifies your brand. When you think of Facebook or Twitter, you think of blue. When you think of YouTube, you think of red.

In this case, I’m going to use pink in the demo app. The primary color for that is this pink (see slide 7). Material design guidelines have all these numbers, 50 to 900. It’s showing you the different palette shades. You have the primary color which is 500. The primary dark color which is 700. The accent color, which is an entirely different contrasting color. In this case, I’ve used yellow.

Prior to material design, we used what we call the holo theme. It was introduced in Android 3.0 and then refined in 4.0. It was introduced to make sure that all the Android apps out there followed some sort of design guideline. With the material design guideline, we can do that using bold brand colors and a lot of typography and imagery.

Get more development news like this

For anything prior to 5.0, we used to use the theme Holo. Now you can use theme AppCompat, which works all the way back to Android 2.1.

A style is something that, if you have a UI element, you would apply to a button, for example. If you want a yellow button, you would apply a yellow color to that button by using a style. If you want your entire app to have yellow buttons, you would take that style and make it a theme.

Style - Theme

How do I apply a theme? All those primary colors that you generated, in our case, which was pink, a darker pink, and your accent color which was yellow. You make sure that you’re using those colors. You can use a style across your entire app.

One of the resources that are really helpful out there, if you’re building an app from scratch, and you want to define some brand colors, is materialpalette.com. In that, you get a bunch of options. You get to choose two colors. The first color would be a primary color. The second color would be your accent color. In this case, it’s pink and yellow.

In materialpalette.com, once you choose your two colors, it gives you a bunch of options. You can use your dark primary color, your accent color, or light primary colors, on different parts of your app. In this way, you can define your brand.

How does this apply to your app? Here’s an example (see slide 12). We generated the primary colors and primary dark colors. The “color primary” is in your app bar. The “color primary dark” goes on your status bar. And the “text color primary” goes on your text, and so on.

If you want to use a theme, make sure to always use the AppCompat theme because you want to make sure it goes back to whatever version you’re supporting. If you want it to go back to Android 2.1, make sure you use this. Your griddle dependency is this line, the latest supported version is 24.1.1:


 compile "com.android.
support:appcompat-v7:
24.1.1"

Style - Typography

Another thing that material design has is typography. I don’t know how many of you here have used sp (scaled pixels) versus dps, but for text, always use sp.

Make sure you don’t go below 12sp. If you try to do so, Android studio tells you that’s the minimum.

Some of the other things that you can use is a bunch of fonts that Google provides. You can get them at fonts.google.com. The default font is “Roboto”. In that you get a bunch of other font tweaks like light, regular, bold, medium, and so on. On slide 13, you can see fonts types and sizes for different elements. Notice that buttons are always all caps.

Another thing you can use is calligraphy. There’s a library out there that you can use for custom fonts in your app, if you want to use something other than “Roboto”.

Next, we move on to imagery.

Style - Imagery

This is one of the most important aspects of material design because by using bold images you know where exactly the user can focus.


compile "com.android.
support:palette-v7:
24.1.1"

In this case, I’m using this Pokémon called Bulbasaur. I’m extracting prominent colors from it, and you can see on slide 14 there are varied shades of green and red. The way you do this is passing your bitmap to your palette, and then the palette listener will generate a bunch of colors for you:


Bitmap myBitmap = BitmapFactory.decodeResource(getResources(), R.
drawable.bulbasaur);

if (myBitmap != null && !myBitmap.isRecycled()) {

    Palette.from(myBitmap).generate(paletteListener);
}

Just like how we saw the six different colors: vibrant, light vibrant, dark vibrant, and so on. All of that will be generated for you. Make sure to do this in a background thread.

One of the things that I wanted to point out was the palette library can be used to highlight certain portions of your app. In the DramaFever app, we have giant master images. We use that, and we extract the most prominent color:


Palette.PaletteAsyncListener paletteListener
        = new Palette.PaletteAsyncListener(){
    @Override public void onGenerated(Palette palette) {
        int defColor = 0x000000;
        int vibrant = palette.getVibrantColor(defColor);
        int vibrantLight = palette.getLightVibrantColor(defColor);
        int vibrantDark = palette.getDarkVibrantColor(defColor);
        ...
}};

In this image (see slide 17), we get a dark shade. If you had an image that had red as the prominent color, then that section would change to red. You can use palette in many different ways to highlight different sections of your app.

A quick recap of style:

  • We talked about color, materialpalette.com, and how we can use the colors generated from that to define your brand.
  • We talked about theme and AppCompat.
  • We talked about typography and using a minimum of 12sp.
  • And we talked about imagery and how to use Palette to extract prominent colors from an image.

In the next section, we’re going to talk about layout.

Layout (9:22)

For layout, we’ll cover:

  • Keylines & Grids.
  • Device Metrics.
  • Responsive UI.
  • Breakpoints.

Layout - Keylines & Grids

Anything that you layout in your Android app has to be on an 8dp baseline grid. You can see on the first screenshot on slide 19, we have the Gmail app. The margin on the left side is 16dp, which is a multiple of eight. The second margin that you have is 72 dp, which is, again, a multiple of eight.

You want to make sure that it’s always on a 8dp baseline grid. This makes it easier for people to understand how the layout works.

One of the most awesome apps in the Playstore is this one: Keyline Pushing app for design testing. It lays the 8dp grid right on top of your app, and by doing this, you can see everything is in that grid. It looks really nice because all the images and icons are aligned well.

Layout - Device Metrics

Another thing in the design docs is device metrics, and this is not just for Android. This is for Android, iOS, and desktop devices as well. You have the width and height, pixels, and dps. You have the screen size and density. All of this is important because when you design for Android, you’re not designing for one screen; you’re not designing for phone or tablet. You’re designing for all of them.

Let’s see how we can use those device metrics to make the layout more responsive.

Layout - Responsive UI

Suppose you have a grid of items. On a phone, you can probably show two columns. On a tablet, you can show four columns. You can do this by using layouts, so when the smallest width is 600dp, for example for a tablet, then you’re going to show four columns.


res/layout/main_activity.xml    # For handsets
res/layout-sw600dp/main_activity.xml    # For tablets

In the DramaFever app, this is what we do. You can see on slide 23; the Nexus 7 shows three tabs, and on a Nexus 9 it shows two tabs. The difference is that we show different layouts depending upon the breakpoint. In this case, the breakpoint is 1024dp, which means that anything above 1024dp, gets the second layout.

Layout - Breakpoints

On slide 24, you can see a bunch of breakpoints that are currently in our design guidelines (check out google’s material docs breakpoints as well).

You can see the 1024dp at the bottom there which differentiates it between handset and tablet. You can also see a bunch of other size buckets: small, medium, large, extra large; portrait versus landscape.

When you’re having a conversation with your designer, don’t think of it in terms of phone and tablet. This was something that we realized along the way. Think of it in terms of breakpoints. If it’s 1024 and above, show a different layout. If it’s 600 and below, show a different layout. It’s different for different screens.

The reason you do this is because you have more screen real estate on tablets. You have lesser screen real estate on phones, so you want to make sure that you’re using it wisely.

Quick recap on layouts:

  • We talked about keylines and grids and how to use 8dp baseline grid.
  • We talked about device metrics.
  • We talked about responsive UI and making your content float to fit the screen size.
  • We also talked about breakpoints instead of thinking of things in terms of size buckets.

Animation (12:47)

We’ll quickly talk about animation. I’m going to focus on what I think is important when you get started with material design. There are two things: surface reaction and shadow.

If you look at this card view on the left-hand side of slide 27, when you tap on it, the touchpoint radiates out. That’s called an “ink ripple.” It indicates touch input.

You can also see that there is a resting elevation of 2dp. When you tap on it, it lifts to your touch. That is indicating user interaction. It’s very subtle.

You don’t have to add buttons like “OK” and “Cancel” because you have your UI elements which are subtly reacting to your touch. These are the two most basic motion or animation there is in material design. One of them is surface reaction, or ripples, and the other one is shadows or elevation.

The gray ink ripple that you see, you can get that by using the attribute ?android:attr/selectableItemBackground. If you use selectableItemBackgroundBorderless, it goes outside of the card views bound.

You can also control the color highlight by using android.colorControlHighlight. Instead of the grey, you can change it to something else.

Quick recap:

  • We talked about surface reaction, and we talked about ripples.
  • We talked about shadow, and resting/raised elevations.

Components (14:23)

Let’s talk about the most common components and backgrounds that you’re going to use in your material design app:

  • Button.
  • Floating action button.
  • Card view.
  • Recycler view.
  • Toolbar and app bar.
  • Coordinator layout.

You can see the demo app on slide 30, and it’s filled with Pokémons. You can get the code from my GitHub repository, it’s forked from Chris Banes Cheesesquare app, but I replaced all the cheese with Pokémon.

The app has a grid view, a list view, and a staggard grid view. The grid view has some columns of Pokémon. The list view has a list of Pokémon. The staggard grid has some text on it.

The app also lets you go to a Pokémon page where you can extract the prominent colors and then you can figure out how card views work, what a button looks like, and so on.

If you’re going to implement material design, you want all these dependencies in your griddle:


compile "com.android.support:palette-v7:24.1.1"

compile "com.android.support:design:24.1.1"

compile "com.android.support:appcompat-v7:24.1.1"

compile "com.android.support:recyclerview-v7:24.1.1"

compile "com.android.support:cardview-v7:24.1.1"

You want palette, if you’re using the Pallete API. Use the support:design library for visuals like floating action button. Use the appcompat library for coordinator layout, and use a recyclervieweror cardview if you’re using any of those.

Components - Buttons

Let’s quickly talk about buttons. You can see the flat design of the buttons on slide 32. There is no elevation, but there is an ink ripple when you touch it. Then you have the raised style of buttons which have some elevation. When you touch it, there’s an ink ripple. Then you finally have the floating action button, or FAB, which is generally used for promoted actions. That is kind of a raised button, but it’s circular.

In our demo app, you can see the button section when you click on the material wall button. You can see the ink ripple radiating out. That is on both Lollipop devices, so anything above Android 5.0.

In the pre-Lollipop device, you can see that you don’t really get that ripple. To do that for post-21 devices, just like how you define it for your regular buttons, you can use selectors:


<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_pressed="true"
        android:drawable="@drawable/bg_button_yellow_pressed"/>
    <item
        android:drawable="@drawable/bg_button_yellow_normal"/>
</selector>

But on pre-21 devices, you want to enclose that in a ripple tag so that it gets its ripple:


<?xml version="1.0" encoding="utf-8"?>
<ripple
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?android:colorControlHighlight">
    <item android:drawable="@drawable/bg_button_yellow_normal" />
</ripple>

Components - Floating Action Button

The floating action button, as I said, it’s a promoted action. For example, in this case, maybe you want to start a show page. That’s what it’s going to do. When I use the lines on the screen, they look at the screen, and they’re like, “I know that this action is starting something.”

There is a guideline for the floating action button as well. The icon within it should be 24x24, and the diameter is 56. But there are various sizes of floating action buttons that you can use:


<android.support.design.widget.FloatingActionButton
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    android:src="@drawable/ic_discuss"
    android:layout_margin="@dimen/fab_margin"
    android:clickable="true"
    app:layout_anchor="@id/appbar"
    app:layout_anchorGravity="bottom|right|end" />

You can use the standard FloatingActionButton widget. If you want to, you can create your own. You can create it in different sizes. You can do whatever you want with it. But the easiest way of doing things is using src to change the icon by changing the drawable. You can also align it anywhere. Over here it says bottom|right|end. You can put it on the left or the top corner as well.

Components - Cards

Let’s talk about cards. Now cards are entry points into something else. You can see the Google keep app on slide 38. When you click on it, the card opens up to show more information. On the Pokémon app, we have all these cards which show different components like palette, button, and info.

The thing about cards is the resting elevation is 2dp and the card raised elevation is 8dp. How would you get a card in your app?


<android.support.v7.widget.CardView android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="@dimen/card_margin">
    <LinearLayout style="@style/Widget.CardContent"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?android:selectableItemBackground"> <!-- API Level 11 -->
        …..
    </LinearLayout>
</android.support.v7.widget.CardView>

You would use the support design library and then use the widget.CardView. You can give it style using Widget.CardContent. Give it a background, which helps so that when you click on it you have the ripple effect. Note that it’s API level 11 and above.

Components - Recycler view

We have the RecyclerView for list and grid. Earlier we used list view but with the RecyclerView you can layout your data in many ways. For that, you can use the AppCompat library if you’re trying to use some widgets:


compile 'com.android.
support:appcompat-v7:
24.1.1'

compile 'com.android.
support:recyclerview-v7:
24.1.1'

You have to use the RecyclerView dependency. On slide 41, you can see a diagram of how it all works under the hood. You have a layout manager. In the previous case, you saw that there was a grid, a list, and a staggard grid. All you have to do is change the layout manager to be the linear layout manager for list; grid layout manager for grids; staggard grid layout manager for staggard grids.

Then you have an item animator that is used for animating adding, and removing items from your list or grid. You have a data set which is all your data items. Then you have your adapter which binds all these data items to your view.

To add a RecyclerView to your layout, put this in there:


<android.support.v7.widget.RecyclerView
    android:id="@+id/my_recycler_view"
    android:scrollbars="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

If you want the scroll bar to be vertical or horizontal, you can do that.

This is a View Item that is constantly repeated on your list or your grid, and you can do it this way:


<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:gravity="center">
<ImageView
    android:id="@+id/avatar"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    tools:src="@drawable/bulbasaur"/>
<TextView
    android:id="@+id/text"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    tools:textColor="@color/black"
    tools:text="Bulbasaur"
    tools:textAppearance="?attr/textAppearanceListItem"/>

Components - Toolbar and app bar

There’s a ton of scrolling behavior. There’re tons of scrollable regions in your app. First of all, let me define what the app bar is, and the toolbar and action bar as well.

They’re all kind of the same thing. The action bar is a term we no longer use. The app bar is now action bar. The app bar is a special kind of toolbar; it’s the top bar of your app. Above that bar, you have the status bar which has your notifications and all the other things. Below that, you have the tab bar. And below that, you have the flexible space.

The screenshot on slide 44 shows the modified toolbar, or the app bar which has navigation icons, filter icons, action icons, and so on.

On slide 45, you can see a common pattern that we’re going to look into. We have the status bar with 24dp, the toolbar which has a standard width of 56dp or 64dp, and the tab bar of 48dp.

Components - Coordinator layout

Let’s go back to our demo app. In it, we have a ViewPager. We have three RecyclerViews in there. As we scroll up, we want the tab to go dark to the top. To do that, we use a CoordinatorLayout. It’s the layout that you would use for doing all of these fancy scrolling animations. You have the AppBarLayout. You have the Toolbar and the TabLayout. Finally, you have the ViewPager which has all of this stuff. Then the FloatingActionButton:


CoordinatorLayout
-- AppBarLayout
    -- Toolbar
    -- TabLayout
-- ViewPager
-- FloatingActionButton

As the ViewPager scrolls, you want the AppBarLayout to listen to the scrolling and react to it. You’re going to add this string - appbar_scrolling_view_behavior:


CoordinatorLayout
    xmlns:app="http://schemas.android.com/apk/res-auto"

Toolbar
    app:layout_scrollFlags="scroll|enterAlways|snap"

ViewPager
    app:layout_behavior="@string/appbar_scrolling_view_behavior"

It’s a special string resource that you use on the ViewPager. It’s telling the app bar that, “Hey, I’m scrolling, and you need to react to it.” The toolbar also needs to have layout_scrollFlags and a bunch of other flags. But the minimum thing that it needs to have is scroll because that’s telling the toolbar that there is a scrolling effect that’s happening below it and the toolbar needs to react to it.

So as soon as the ViewPager is scrolled by the user, the toolbar reacts to it by going up and then it gets dark.

Now we have a status bar, underneath it, we have a toolbar, and lastly we have flexible space. We’re going to try and put an image into that flexible space.

You have the status bar, the toolbar, and then the flexible space. The second part of the app in the detail activity. You have the CoordinatorLayout and what we are trying to do is as we scroll up, we want the image to collapse and then we want the toolbar to show up.

We’re going to start with the CoordinatorLayout layout and then have the app bar layout. Then app bar layout should have the collapsing toolbar layout because you want the image to collapse. Then you have the ImageView under it and the toolbar. Then you have a NestedScrollView which is like a ScrollView but as special kind. It has tons of UI elements within it. And on top of that, you’re going to layout the floating action button:


CoordinatorLayout
-- AppBarLayout
    -- CollapsingToolbarLayout
        -- ImageView
        -- Toolbar
-- NestedScrollView
    -- LinearLayout
        -- CardView
        -- Button
-- FloatingActionButton

For the next scroll view, just like we did for the ViewPager, you’re going to add the same special string resource:


CoordinatorLayout
    xmlns:app="http://schemas.android.com/apk/res-auto"

CollapsingToolbarLayout
    app:layout_scrollFlags="scroll|exitUntilCollapsed"

NestedScrollView
    app:layout_behavior="@string/appbar_scrolling_view_behavior"

The appbar_scrolling_view_behavior which is telling your CollapsingToolbarLayout that there is a scrolling effect happening below that. You also need to add the layout_scroll against scroll. You can add various flags and exitUntilCollapsed is one of them. When you scroll the next scroll view below, the toolbar layout responds to the scrolling, and it collapses the image view.

A quick recap of what we talked about:

  • We talked about buttons: flat, raised, and floating action buttons.
  • We talked about floating action buttons being promoted actions.
  • We talked about card views as entry points to something else.
  • RecyclerView for lists and grids.
  • We talked about toolbar and app bar, and how app bar is a special kind of toolbar.
  • We talked about CoordinatorLayout and all the scrolling behaviors and techniques that you can use.

Conclusion (24:20)

Here’s a bunch of resources that I used while working on the material re-design at DramaFever:

I did the course at Udacity, which I recommend to everyone. The Android developer docs are also great, specifically the material design part. Google material design guidelines at google.com/design is good. Material Doc is a user-generated documentation of all the various patterns and components that are out there.

Codepath has a good section on handling scroll behaviors. Also the Plaid app by Nick Butcher. He has done some really amazing material animations so do check that out.

Resources

About the content

This talk was delivered live in July 2016 at 360 AnDev. The video was recorded, produced, and transcribed by Realm, and is published here with the permission of the conference organizers.

Yash Prabhu

Yash Prabhu leads the Android team at DramaFever and has been developing Android apps since 2010. She has spoken at several Android meetups and conferences over the past three years. In her spare time, she volunteers at Girl Develop It Philadelphia, Code For Philadelphia and Google Developers Group Philadelphia as a teaching assistant, instructor, mentor and organizer.

4 design patterns for a RESTless mobile integration »

close