How To Create A Material Style Action Bar On KitKat And Older Android Versions

NOTE

This method of achieving a material style action bar was found before Google released the latest support libraries. At the moment, it’s a lot wiser to make use of the support libraries. This method was nothing more than a hack to begin with. For info on how to use the AppCompat library, you can check out this blog post on the android developers blog.

 

When I saw Material Design in the Google I/O keynote, I was very excited. At first, I thought I’d wait for some solid material/reference before trying things. However, after some point I couldn’t resist the urge and started redesigning my app following the new design guidelines. Of course, the first thing to come my way was supporting older Android versions. I thought for some time and figured that I’d be able to have a nice material-like action bar using a custom view in my action bar. I did that and I had a pretty good looking result. One thing that caused me pain was that I had to have around 10 lines of code in each and every Activity in my app. While working on a new app today, I realized that I could achieve the same effect (or an even better one) using much simpler tricks.

Action Bar Height

First up, we have to increase the height. To do this we will add the following line to our app’s theme. Where @dimen/action_bar_height is 56dp.
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<item name="android:actionBarSize">@dimen/action_bar_height</item>
</style>

Action Bar Icon

Secondly, we have to hide the app icon. To do this we will create a custom action bar style and hide the icon there.
<style name="AppTheme_ActionBar" parent="android:Widget.Holo.ActionBar.Solid">
<item name="android:icon">@drawable/actionbar_icon_placeholder_compat</item>
</style>

@drawable/actionbar_icon_placeholder_compat is just a transparent 12dp wide xml drawable.
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<size android:width="12dp" />
<solid android:color="@android:color/transparent" />
</shape>

Action Bar Title

We then have to increase the size of the action bar title. In order to do this, we create a custom action bar title style
<style name="AppTheme_ActionBar_Title" parent="android:TextAppearance.Holo.Widget.ActionBar.Title">
<item name="android:textColor">@android:color/white</item>
<item name="android:textSize">20sp</item>
</style>

and add it to our action bar style
<style name="AppTheme_ActionBar" parent="android:Widget.Holo.ActionBar.Solid">
<item name="android:icon">@drawable/actionbar_icon_placeholder_compat</item>
<item name="android:titleTextStyle">@style/AppTheme_ActionBar_Title</item>
</style>

Overflow Icon

Another thing we have to do is creating a custom style for our overflow button.
<style name="AppTheme_ActionBar_Overflow" parent="android:Widget.ActionButton.Overflow">
<item name="android:src">@drawable/ic_ab_overflow_compat</item>
</style>

we then add this style to our app’s theme:
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<item name="android:actionBarSize">@dimen/action_bar_height</item>
<item name="android:actionOverflowButtonStyle">@style/AppTheme_ActionBar_Overflow</item>
</style>

Action Bar Background

Setting the action bar background is pretty straightforward. We just have to add the following line to our action bar style:
<style name="AppTheme_ActionBar" parent="android:Widget.Holo.ActionBar.Solid">
<item name="android:icon">@drawable/actionbar_icon_placeholder_compat</item>
<item name="android:titleTextStyle">@style/AppTheme_ActionBar_Title</item>
<item name="android:background">@color/apptheme_primary</item>
</style>

Action Bar Shadow

For the action bar shadow we add the following line to our app’s theme:
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<item name="android:actionBarSize">@dimen/action_bar_height</item>
<item name="android:actionOverflowButtonStyle">@style/AppTheme_ActionBar_Overflow</item>
<item name="android:windowContentOverlay">@drawable/actionbar_shadow</item>
</style>

@drawable/actionbar_shadow is an xml drawable (gradient) with a height of 4dp
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<size android:height="4dp" />
<gradient
android:angle="270"
android:endColor="@android:color/transparent"
android:startColor="@color/gradient_start" />
</shape>

Home As Up Icon (Indicator)

And finally, the home as up indicator (or the back button). This is where things go a little tricky. Well, I guess, still not so tricky. Basically, here we have to have a slightly “different” icon style. They won’t be squares but rectangles. The reason for this is that we need some kind of space on the left side of the button and we insert that empty space inside the png drawable. I hope the following image can get the point across.

home_as_up_exp

One more thing I had to do here was to scale down the arrow a little bit. I think it fits better a little bit smaller. In any case, I’ve added mdpi, hdpi, xhdpi and xxhdpi versions of these icons to the zip package available at the bottom of the page, so you don’t have to worry about these. Just copy them in your project and you should be good to go!

Other than the drawables, we have to add the following line to our app’s theme:
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<item name="android:actionBarSize">@dimen/action_bar_height</item>
<item name="android:actionOverflowButtonStyle">@style/AppTheme_ActionBar_Overflow</item>
<item name="android:windowContentOverlay">@drawable/actionbar_shadow</item>
<item name="android:homeAsUpIndicator">@drawable/ic_ab_up_compat</item>
</style>

Navigation Drawer Icon

The navigation drawer icon works the same way the home as up icon does. Again, you can find the drawables in the package provided below.

Navigation Drawer Shadow

I feel that the shadow which comes with a new app doesn’t really fit the material style in overall. I’m using the following xml drawable (gradient) as my navigation drawer shadow.
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<size android:width="16dp" />
<gradient
android:endColor="@android:color/transparent"
android:startColor="@color/gradient_light_start" />
</shape>

Result:

1 2

Download Resources

I’ve put all the styles and drawables into this zip file. You can just download it and copy its contents to your project directory accordingly!
Google Drive

Sample Application

You can find my sample application and its source code on Github.

Advertisements

14 thoughts on “How To Create A Material Style Action Bar On KitKat And Older Android Versions

  1. I appreciate your try in material design for older versions. Even I have tried most of it by failing multiple times. I have a questions still about the animation of action bar icon. I believe u have seen them. New updates for Google Newsstand, Google+ and Play Store have that actionbar animation. Any idea how they achieve that in KitKat and lower version API’s? If you have any idea about it I would like to know!

    Liked by 1 person

    • Yes, I have seen the animation. I know when and where to trigger it, but unfortunately, I don’t know how I can animate the icon.

      We could animate the icon if we were to use a custom view in the action bar, but that defeats the whole purpose of this post and is something I don’t want to get into. Google might be using a custom view as I said, but I don’t think they’d resort to such a messy solution. Perhaps they have some kind of early access to some functions of the upcoming versions of the support libraries(?)…

      If I manage to figure something out in the near future, I’ll post the results.

      Like

      • Thanks for your valuable reply. Even i thought the same as some supprt libraries which no available to normal developers yet. By the way for beginners in Material Design it will be good start. Keep moving 🙂

        Like

    • You might have already figured this out by yourself but I thought I’d post anyways. Apparently, you have to use the new AppCompat library. In order to achieve the arrow animation, you’ll have to use the ActionBarDrawerToggle from the v7 library instead of the v4 one. You will also need a toolbar instead of your action bar. Information on how to use a toolbar can be found here: http://android-developers.blogspot.com/2014/10/appcompat-v21-material-design-for-pre.html.

      Once you have a toolbar set up and and your ActionBarDrawerToggle is from v7 support library, the only thing you have to do is to reference your toolbar when setting up your drawer toggle. Previously, we’d reference a drawer drawable here.

      Like

    • That’s because you need to have a modified platform directory under your sdk/platforms directory. I thought I had put the information in build.gradle file, but as it turns out, I forgot. In any case, I’ve update the project files so you can check the gradle file again, or you can just do the following:
      download this (https://docs.google.com/file/d/0B3kP5OEGFYUBZWxacV9jVjVKOGs) platform folder and copy it to your sdk/platforms directory.

      Hope it helps!

      Like

  2. Thanks, very interesting article. But there is one detail that I think should be change.
    When you click on the drawer icon it shouldn’t be translated to the left. I tried to avoid it but I didn’t find out to do it.

    I used a different implementation to create a material style action bar. I replaced the logo with the drawer icon.
    You can see the code there: https://github.com/StephaneBg/ScoreItProject

    Like

  3. Can you please help me with this issue:
    I’m trying to set a shadow for the action bar for all my activities, on both Lollipop and pre-Lollipop versions, no matter how the ActionBar was created.
    For most of the activities, I use “Theme.AppCompat.Light” and they work fine.

    However, for some activities, I use a “Theme.AppCompat.Light.NoActionBar” , and I use “setSupportActionBar” on the toolbar on them.
    For pre-Lollipop, I use a FrameLayout that has android:foreground=”?android:windowContentOverlay” , below the toolbar.
    This solution works fine, but on Lollipop, I don’t see any shadow… Setting the elevation also didn’t do anything.
    What should I do to make the shadows appear (and look the same for all activities) right?

    Like

      • A side note for CardView: you can set outlineProvider to bounds instead of background if your background is transparent or null. This will use the view bounds as shadow reference instead of the background.

        EDIT: What the hell did I write? I was thinking: “A side note for ELEVATION”.

        Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s