We were all hoping that the new support APIs included Material Design, the new theme adopted since Android 5.0 Lollipop. And it luckily happened: this new theme is included in AppCompat 21. So be aware that if you are using it for previous projects, the transition won’t be straightforward.
If you want to know more about this topic, I have another article from a talk and a more complex example in another repository on Github. Enjoy!
Anyway, in this post I want to give you the most basic tools to create an app that uses Material as its main theme, and functional from API 7. I’m not getting into details on how to take the most out of this theme (that will require some extra tutorials), but to get it prepared to work backwards, even with transitions functional in Lollipop.
One minor clarification: Lollipop transitions are not backwards compatible, so at the moment you won’t be able to see those smooth transitions in pre-21 devices.
Setting up your project
First, you will need to create a new project and set ActionBar compatibility, even if you are only supporting 14+ devices. The Material theme is included in it. Set the compile sdk version to 21. Your build.gradle should be something like this:
[groovy]
android {
compileSdkVersion 21
buildToolsVersion "21.0.0"
defaultConfig {
applicationId "com.antonioleiva.materialeverywhere"
minSdkVersion 14
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
…
}
dependencies {
compile fileTree(dir: ‘libs’, include: [‘*.jar’])
compile ‘com.android.support:appcompat-v7:21.+’
}
[/groovy]
Specify the Material Theme
It’s now important that your theme extends Theme.AppCompat. Now, the AppCompat Theme includes everything you need to support Material Design in previous versions. You will see that I’m using a Base theme and overriding the final theme in values-v21. This is because I want that Lollipop uses its nice transitions.
values/themes.xml
[xml]
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="AppTheme.Base"/>
<style name="AppTheme.Base" parent="Theme.AppCompat">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimary</item>
<item name="android:windowNoTitle">true</item>
<item name="windowActionBar">false</item>
</style>
</resources>
[/xml]
values-v21/themes.xml
[xml]
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="AppTheme.Base">
<item name="android:windowContentTransitions">true</item>
<item name="android:windowAllowEnterTransitionOverlap">true</item>
<item name="android:windowAllowReturnTransitionOverlap">true</item>
<item name="android:windowSharedElementEnterTransition">@android:transition/move</item>
<item name="android:windowSharedElementExitTransition">@android:transition/move</item>
</style>
</resources>
[/xml]
We set some primary colors and remove the ActionBar. We don’t want to show the ActionBar because there is a new substitute in the game: the Toolbar. I will talk about it a bit later.
You just need to set the theme in the AndroidManifest.xml.
[xml]
<application
…
android:theme="@style/AppTheme">
…
</application>
[/xml]
Setting the Toolbar
The toolbar is basically what we were used to know as the ActionBar. The most important difference is that this toolbar is now part of our layout, so that we can play with it in any way we consider: animations, drawer overlay, etc.
This is basically what we need to add to our layouts. It may be interesting to create it in a separate layout and include it in the other ones:
[xml]
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimaryDark"/>
[/xml]
So how does it change our way to work with the toolbar? Almost everything will be the same, we just need to remember to notify the Activity that this toolbar will be its ActionBar. Don’t forget that your activities must extend ActionBarActivity
[java]
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getLayoutResource());
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
if (toolbar != null) {
setSupportActionBar(toolbar);
}
}
[/java]
And that’s it, now you can set your menu, title and the rest of ActionBar properties usign the methods you already know. I find it useful to create a BaseActivity which is in charge of doing this task, and make the other activities extend this one.
You can now add a navigation drawer, and you will see that the drawer appears over the toolbar, just as the google design guidelines recommend.
Lollipop Activity Transitions
As I mentioned before, transitions are not available in pre-21 devices, so we need a way to overcome this issue. The support library provides a good set of compatibility classes that will help us use these new features with less code. This is a typical move transition, in which some shared elements are animated into the new activity:
[java]
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(
activity, transitionView, DetailActivity.EXTRA_IMAGE);
ActivityCompat.startActivity(activity, new Intent(activity, DetailActivity.class),
options.toBundle());
[/java]
That’s nice. With ActivityCompat and ActivityOptionsCompat we don’t need to check the device version and our code will be cleaner.
Conclusion
With these simple steps, we are now prepared to start an Android app using Material Design and the new Toolbar. There is much left to explain about the Material theme and how to configure it, but this is a good first step into the new era of Android design.
You can see a working example in this project in my Github.
Pretty cool. spent all night looking for this
Great introduction to the new AppCompat lib. Thanks! 🙂
Thank you. Pretty easy and quick to understand!
This is great. Thanks for the info.
One question though: When a Contextual ActionBar is shown (for example, when highlighting text in an EditText field), it will push the Toolbar down. do you know how to make it go overtop the Toolbar?
Use true
Set android:windowActionModeOverlay as true in your styles.xml
Hello. Sorry but can you explain me what this is because i dont understand anything. What app do i have to use? Is appcompat an app at all?
AppCompat is a library that you can use to implement Material Design in old Android versions.
Thanks
Thanks.Nice post.Can’t wait to get my hands on those support libraries!
I am on CM11 Android 4.4.4.. I made a test activity that extends ActionBarActivity .. exactly what you have given above. Everything is just as is, but the toolbar object is never created. It is null. I can’t get the toolbar working. I have checked the support libraries, imported the correct classes but still it does not instantiate.
Have you figured this out yet? I’m trying this and get the same error. I downloaded the sample project from github and it compiles without a problem.
No i haven’t figured it out yet. Still getting the same issue!!!
Did anyone figure this out? I too have the same problem!
Got it working by updating andriod studio 🙂
I was using the Toolbar layout within a DrawerLayout Activity and was getting null when finding the view.
I fixed my issue by including the toolbar layout in my drawer layout xml with:
just use this in style
Cool as usual.
I’d like to see further posts explaining more about the Toolbar customization.
As you’ve said, and I’ve read to Chris Banes (here http://goo.gl/pu0dXa)… ” I’ve seen most teams declaring the Toolbar in it’s own layout file, and then in your other layouts. That’s just one way though.”
Bu the way, I don’t like the new design guideline where the NavDrawer is over the toolbar (Google Newsstands app), I prefer the approach in the Google Play Store or Google Photos app.
Cheers
Then just don’t remove it in the theme declaration and keep using it as usual. Or add to your layout and set it in a LinearLayout with a DrawerLayout. Your are not constrained to anything, you can put your Toolbar wherever you want.
i can’t find file drawe ic_ab_drawer and file drawe drawer_shadow . can helf me. thank you
Hello. Can you explain this? Do you mean not to use Toolbar and go back to ActionBar?
I want to have the app icon at the left of the actionbar like it used to be. Is that still possible?
You have space for an icon, yes, but it is not recommended. You can use setLogo(), but the result won’t be exactly the same as the Holo theme.
Thanks thats good to know. One more question: How can I apply a set of styles to actionbar using the
@style/MyActionBarStyle
It doesn’t seem to work anymore or I am missing something on MyActionBarStyle style.
Sample App Running GalaxyS4 4.4.2 but that picture not same
it’s only work 5.0 ?
Transitions only working on lollipop, not backwards compatible.
what if i want to use this in previous versions?
You can’t
Thank You very much!!!
Very good! I hope you continue with the tutorials of android 5 😀
Great post.
colorPrimaryDark isn’t working on kitkat, I thought that maybe it would work out of the box.
Found the answer here
http://stackoverflow.com/questions/26440879/how-do-i-use-drawerlayout-to-display-over-the-actionbar-toolbar-and-under-the-st
Thank you for sharing this with us. Very helpful.
How could I get a settings screen that has an ActionBar?
I mean, it’s supposed to either extend from PreferenceActivity or have the ability to use PreferenceFragment, but PreferenceActivity doesn’t extend from ActionBarActivity, and PreferenceFragment isn’t available on pre-API11 …
Can you please help?
I don’t know of a direct way, you could either copy PreferenceFragment and make it extend support Fragment (or the same with PreferenceActivity) or search something on Github. There’s probably already solved by someone else.
I see. It’s weird that so far there is no way to do it.
Is it possible perhaps to use the Toolbar class as a view above the ListView of the PreferenceActivity ? It doesn’t even have to have the same functionality of an ActionBar, just show a title and look exactly the same as an ActionBar.
Yeah you could, but you won’t be able to use the AppCompat theme in that activity.
The best way is to use PreferenceFragment. I have good experience with android-support-v4-preferencefragment library: https://github.com/kolavar/android-support-v4-preferencefragment.
I am having the same problem, after upgrading to 21 my PreferenceActvity lost its actionbar, I managed in hacky way to bring it back – but it does not have material like look (http://stackoverflow.com/questions/26439139/getactionbar-returns-null-in-preferenceactivity-appcompat-v7-21/26449687#26449687). I am using headers so transition to FragmentPreference is not possible (as far as I know). I think I will have to live with no actionbar – or live with no headers.
I found a solution to this (Toolbar on Preference Screen). I was digging around Google and found this great blog post. Basically what the dev did was create an activity and embedded his PreferenceFragment right into it. I replaced his TextView with my Toolbar and added my PreferenceFragment as the fragment (his only contained one list_preference, mine has my entire preference screen).
http://wptrafficanalyzer.in/blog/embedding-listpreference-in-an-activity-using-preferencefragment-in-android/
Credit to: George Mathew
http://wptrafficanalyzer.in/blog
Hey, Try this:
http://stackoverflow.com/a/26564401/507142
This helped me. Thanks!
“ActivityOptionsCompat.makeSceneTransitionAnimation”
not seems to be working in lolipop also. It’s showing normal fading behaviour. Do I need to do some additional config for it?
The example I uploaded to Github is fully working, you can compare with it. You basically need to specify the view involved in the animation from origin and set a transition name to the destination view, as well as specify the animation in the theme or programmatically in the activity.
You are a life saver!!
Thanks for this awesome tutorial. I tried to use it with the fragment drawer made by android studio but it crashes now… Telling me that it cannot inflate my layout anymore. In my case the DrawerLayout looks like yours except for the ListView thingy… It’s a fragmenr which inflates a ListView Layout. And the logs tell me the error is somewhere in there:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.brobox.toolbartest/com.brobox.toolbartest.MainActivity}: android.view.InflateException: Binary XML file line #23: Error inflating class fragment
I have the exact same problem. Did you figur this out?
To solve this, you need to replace, getActionBar().getThemedContext() with getActivity in the fragment where it is setting the adapter for the list.
it should clean everything up, because actionBar no longer exists since we are using a toolbar.
I’m not seeing where you switch the DetailActivity to have an Up caret rather than the burger. Can you comment on this please? Specifically how to set the click listener. Thanks.
I do it in the BaseActivity (both things).
I appreciate the quick reply!
I see where those are done in BaseActivity, but where in DetailActivity do you tell it that it needs the up caret? I’m sorry if I sound like i’m repeating my question, but simply extending BaseActivity gives the burger, not the up caret.
Never mind, I realised my mistake now. This was all coming from me changing the fragment in the activity and wanting to change the icon based on that.
Creating a values-v21/themes.xml file just for the transition XML attributes isn’t actually necessary… they can be added to the values/themes.xml file and will simply be ignored on pre-Lollipop versions of Android.
Yeah, your are right, it’s not necessary at all. Just my obsession of not having errors shown in XML. But of course, it will work if only one theme is used. Thanks for the clarification!
Seems I misposted this the first time…
Thanks for this awesome tutorial. I tried to use it with the fragment drawer made by android studio but it crashes now… Telling me that it cannot inflate my layout anymore. In my case the DrawerLayout looks like yours except for the ListView thingy… It’s a fragmenr which inflates a ListView Layout. And the logs tell me the error is somewhere in there:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.brobox.toolbartest/com.brobox.toolbartest.MainActivity}: android.view.InflateException: Binary XML file line #23: Error inflating class fragment
It’s difficult to say without seeing the code. The best advice I can give you is that you try to do the same as you can see in my example and make it work, and then go little by little changing things and checking until you get what you want.
Thanks Antonio.
Why do you set ?attr/colorPrimaryDark to background of Toolbar.
It should be colorPrimary, I think.
https://developer.android.com/training/material/theme.html
Yeah you are right, that was my mistake.
Really nice and awesome kick explanation 😀 Thank you so much. Could you pls explain further for individual widgets on how to apply the material theme effects 🙂
How to change status bar color?
thanks !!!
Awesome post! Playing with the Inbox app from Google on my Nexus 5 running 4.4.4, I find that the navigation drawer does not sit on top of the action bar when expanded. The Material Design spec on side navigation bar (Ref – http://www.google.co.uk/design/spec/layout/structure.html#structure-side-nav-1) recommends Android developers to float navigation drawer on top of the action bar and below the status. Same is the case with Google’s Play Store app. Is there trend to not float the navigation drawer on top of the action bar? Or, am I missing something?
In theory, design specs say that the drawer should sit on top of the toolbar, but Google is going against its own guidelines as usual. The only one doing it that way is Newsstand I think.
Awesome now i am able to developer android 5.0 Apps
So The Transtition ONLY Works with Lollipop right ?? in Device 4.4 or 4.2 and under… The Image Wont Zoom in/out just like your Sample…. 😮
nice Tutorial btw.. its Work Fine in my Emulator 5.0
Yeah, transitions won’t work in pre-lollipop devices.
Nice Post! How to add tabs in new toolbar?
Thx , but the Google Play app is using a drawermenu as Android L and works fine on Android 2.3. It is a library of support?
Just want to also let people know:
If you’re menu’s are showing up in the Overflow for the toolbar, follow the same steps as the old actionbar: http://stackoverflow.com/questions/18452578/items-in-actionbarcompat-are-showed-always-in-overflow/26594611#26594611
Was stuck on this for quite a while.
cc: @AntonioLeiva
I’ve just created a new project with a Navigation Drawer but after adding your code I get an exception for an xml error :/
Thanks Antonio
Awesome Introduction to Material Design implementation.
Awesome Material Design implementation… Really Great….
also i have one doubt if im using AppTheme (Material Dark Theme) but the alert should be in a AppTheme.Light (Material Light Theme), tell me sollution.
Use the ContextThemeWrapper as a context for your AlertDialog.
hi.. Thanks for your replay…
also i have another doubt… how to create the toolbar in Android 2.1 that toolbar title is center titl and How to create the contex menu in all the version like 4.4 menu below the actionbar. Can you tell me the solution…
When you create a new Android project with appcompat 21 there is no more actionbar icon by default. Is it normal? I try to set it in XM or programatically but it does not work. I’ve seen I can do that in you toolbar in your drawer but I don’t need a drawer in some of my activities.
Try this – http://stackoverflow.com/questions/26966854/app-compat-actionbar-v21-app-icon-is-not-showing/27442133#27442133
Nice article, thanks!
The Material Design example would have been better if it demonstrates how the drawer layout works with item slection instead of just showing a blank drawer layout.
Probably, but that’s not new in Lollipop, drawer works the same as in previous support versions.
Thanks!very nice
Hi all, my Android Studio update SDK 21, when i imported this project & build. this is error message:
Error:A problem occurred configuring project ‘:app’.
> Could not resolve all dependencies for configuration ‘:app:_debugCompile’.
> Could not find any version that matches com.android.support:appcompat-v7:21.+.
Searched in the following locations:
https://jcenter.bintray.com/com/android/support/appcompat-v7/maven-metadata.xml
https://jcenter.bintray.com/com/android/support/appcompat-v7/
Required by:
MaterialEverywhere-master:app:unspecified
Please help me to fix this bug.
Thanks
Did you update your support library too?
Hello, some time ago I follow your posts, my question is about home icon, is possible to implement an animation like the latest version of playstore?.
Thanks, really nice post!
Awesome man! You rock. Thanks for the tutorial. Well, I am waiting for quite advanced steps.
On a device running Lollipop, I noticed that the sample app doesn’t show the transition animation when the back button is pressed on the toolbar (unlike the case when the device back button is pressed at the bottom). Shouldn’t the behaviour of the toolbar back button be the same as that of the device’s back button?
Thanks!
I wonder as well why the actionbar home button breaks the transition.
Could it be that it has its own default transition overwriting the activity transition?
How could I avoid this?
Overwriting onOptionsItemSelected did the trick:
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
Great tutorial, thanks 🙂
But why does the example different from the gif you add??
What do you see differently? Transitions only work on 5.0, but the rest should be the same.
Well, one thing is transitions and you explain,
and the other is in example there is a list, and in the gif there is a grid, but that is not a problem :p my point was about animations.
thank you 🙂
Yeah, the reason about that is because I used a N7 to develop it, and maybe it’s not very well adapted to a smartphone size.
Another question, why did you call DetailsActivity.java from a static method inside it, and not from the HomeActivity.java using the regular way?
Hello i had a problem with the back and home button in the action bar… It doesn’t work in some devices can you help me out please
I declared them in the manifest and it doesn’t work. see the manifest http://pastebin.com/k6uQdLRD and I did as you did in the code…(Your code work and mine don’t :()
I have another doubt… how to create the toolbar in Android 2.1 that toolbar title is center and How to create the contex menu in all the version like 4.4 menu below the actionbar. Can you tell me the solution…
Thanks for the nice and easy Tutorial,
I have not tried yet, but one question, I m using FragmentActivity, myactivity extends FragmentActivity, and i saw on the tutorial that we have to extend “your activities must extend ActionBarActivity”, So does everything will work if i change from FragmentActivity to ActionBarActivity, My app minimum sdk version is API 14+.
ActionBarActivity extends FragmentActivity, so shouldn’t be much painful
I downloaded the project and imported it into eclipse using import gradle project. but there is not no project showing up when I click on browse for Android Application configuration to choose a project to run in the avd. I have installed all the support libraries and also api 21 from sdk manager.
Thanks alot for this…really helpful..!
Thank you very nice explanation to someone who want to migrate from old styles to materials styles.
Youre the best keep up the good work
thanks !!!
This is my case Activity1 contains ImageView1
Activity2 contains ViewPager which itself contains Fragment1
Fragment1 contains ImageView2
But the animation from Imageview1 to ImageView2 not work. Any ideas?.
It’s possible that you need to delay the transition until fragment 2 is loaded. You need to use postponeEnterTransition() in onCreate() and then call to startPostponedEnterTransition() when you know the image in Fragment1 is already loaded.
Thank you very much !!
Can you please give an example project(Github) with searchview on the new lollipop toolbar with search listview fetching from sqlite database?
I had a project already in production and I want to add that library I use an actionBar in a drawertoggle but when I replace in my manifest file this android:theme=”@android:style/Theme.Holo.Light.DarkActionBar” >
for
android:theme=”@style/AppTheme”>
I got a runtime exception when launching the app it says java nullpointer exception…
Do you have any idea?
Thank you
Hi, I imported your code in android studio. Transaction animation doesn’t work! Detail activity starts with normal transaction (comes from right to left). I’m testing this on android 4.4.2. Am i missing something?
I really appropriate if you give me some tips. It’a a matter of life and death!!!
As I explained in this article and some other comments, transitions are not backwards compatible. Transitions only work on Lollipop.
There is a unofficial “backport” of transition animations here – https://github.com/guerwan/TransitionsBackport, it it helps
Thanks.. really helpful tutorial, and source code on github.
The transition only run on devices with android 5.0 version, so if You tried this on per-lollipop device the transition won’t take place.
Well, ViewOutlineProvider needed for FAB is not available 🙁
Nice graph, Thanks!
Great. Thanks for the information.
Not working on my S3.
What is not working?
Thank you very much for this very clear post!
But I have a great problem: I tried everything you wrote in your code, just copying it eventually, but whatever I do, I keep getting the IllegalStateException: do not request Window.FEATURE_NO_ACTION_BAR etc.
I have been looking for an answer for weeks, but still nothing.
Since I know that actual help is hard to get leaving you just a comment here, I just wanted to know if anyone has already reported to you my same issue, or anything similar.
Thanks again!
I had the same problem.
I changed android:windowNoTitle to windowNoTitle and it worked.
Hey when i use my app in jellybean it does not have material design but have a basic app layout without elevation . Its working absolutely fine on lollipop .
Help me plzzz
Elevation is not backwards compatible, so you won’t see any shadows that rely on elevation for pre-lollipop
the dialog in my app is NOT appearing in material style but in jellybean style.
and even my buttons are using pre-lollipop style.
Help me . i m just a 13 year old boy
Not everything is ported to pre-lollipop versions in AppCompat. You’ll need a library for dialogs and your own style customization for buttons.
Thanks a lot AntonioLeiva 🙂 This blog helped me a lot.. Am following you 🙂
It was one of the first tutorials that I followed and it worked incomplete. The Toolbar is showing up with the colors we mentioned in resources, but the notification bar color is still black in my 4.4.4 Android One Plus One phone.
Btw, in your toolbar.xml, you mentioned the color of toolbar to be colorPrimaryDark but in Android Design guide, the color of toolbar should be colorPrimary.
P.s Do you know any bugs in Android Studio 1.2 Beta? It gives me rendering errors and class not found…. But they were working before upgrade.
Thanks for your contributions.
@Antonio Can you please check my library here:
https://github.com/AndroidDeveloperLB/MaterialPreferenceLibrary
It’s a partial backport of the Preference-classes so that you could have a material-design on the PreferenceActivity.
This is quite missing from the support library. Only similar thing I’ve found is this:
https://android.googlesource.com/platform/development/+/master/samples/Support7Demos/src/com/example/android/supportv7/app/AppCompatPreferenceActivity.java
Absolute best tutorial on getting started with AppCompat and Material design/animations.
This fills the huge gaps in Google’s docs which are nothing but airy fairy overviews without any useful implementation notes.
How can I add entries in the navigation drawer? I have tried integrating some navigation items but it is not working. Will you be able to send me some tips? Thank you
i clone your, it not run: shared element must be null…
What if I wanted to do the same transition, but among Fragments contained in different Activities likes this:
(Activity A) (Fragment A with list) –> (ActivityB) (Fragment B detail)
Any idea how I could achieve the same with this setup?
Hi 🙂
I have a question about Material design added in Android Studio wizard. I have asked an question about it on stackoverflow, but can you read it and help me if you know the answer?
Link: http://stackoverflow.com/questions/32788212/android-studio-add-an-activity-to-mobile-material-design
Animation effect not working in pre-lollipop device
Yeah, transitions are not available in pre-lollipop. The compatibility methods just ignore old versions (don’t make them really “compatible”).