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.
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 recyclerviewer
or 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 RecyclerView
s 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:
- Udacity - Material Design for Android Developers
- Android Developer Docs - Material Design
- Google Material Design Guidelines
- Material Doc
- Codepath
- Plaid app by Nick Butcher
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.
Receive news and updates from Realm straight to your inbox