Styling tabs in the Android action bar

I’m currently in the process of putting the finishing touches on the Android version of Find My Train. Since design detail is a major focus in the app, I’m delving deeper into some of the UI elements than might be done on a typical app. My most recent change was to tweak the color of the tabs on the action bar to match the color scheme of the app. This turned out to be surprisingly tricky, so I’m documenting it here. The default color looked like this:

2013-08-27 11.37.22As you can see, the little indicator of the active tab is a blue color that doesn’t really go along with the rest of the app. So, looking into this, there’s a bit of info in the official android docs here:

http://developer.android.com/guide/topics/ui/actionbar.html#Style

However, it doesn’t go into much detail about how to actually style the tabs. I wandered through a lot of stack overflow questions about it, but wasn’t very satisfied with any of the answers I saw. I also found this site which generates tab bar styles automatically for you:

http://jgilfelt.github.io/android-actionbarstylegenerator/

I tried it out, and it generated a huge number of resource files, plus it was using images for the solid color parts, so I wasn’t very happy with it.

Finally, I checked out some of the sample code for ActionBarSherlock here:

https://github.com/JakeWharton/ActionBarSherlock/tree/master/actionbarsherlock-samples/styled

This gave me an idea of how the style needed to be structured, but seemed incomplete (I couldn’t find some of the referenced drawables, like “ad_tab_unselected_holo”). Between the two examples, I was eventually able to figure things out and build a working solution.

How Action Bar tabs are styled

To control the style on the tabs, you’ll need to do the following:

  1. Create a custom theme for your app, which you’ll probably want to put in styles.xml, and reference your tab styles for each part you want to customize
  2. Create styles for each part of the tabs
  3. Set your app to use the custom theme via AndroidManifest.xml

There are several parts of the tabs that you can customize, and the official documentation seems a little misleading on what they do, so I’ll rephrase here:

  • actionBarTabStyle – This determines the style of the tabs themselves. The tab is the area that includes the text, its background, and the little indicator bar under the text. If you want to customize the indicator like I did, you need to alter this one.
  • actionBarTabBarStyle – This determines the style of the overall tab bar. It includes the whole container that includes all of the tabs.
  • actionBarTabTextStyle – this one I didn’t use, so I’ll assume the official docs explain it properly.

To give you a better idea of how the actionBarTabStyle and actionBarTabBarStyle work, I’ve included a screenshot below, where the actionBarTabStyle has the background set to red, and the actionBarTabBarStyle has the background set to blue. You can see how the blue background covers the whole tab bar area, and the red backgrounds cover each tab.

2013-08-27 20.16.46

Changing the indicator color

My main goal was to change the indicator color under the active tab, but I also wanted to change the highlight color that shows up when the user clicks the tab. Here’s how I ended up doing it:

  1. Create the theme for the app, the action bar, and the tabs. We need to set the background for the tabs to the “tab_bar_background” drawable.

    <style name="FindMyTrain" parent="Theme.Sherlock">
    <item name="android:actionBarTabStyle">@style/FindMyTrain.ActionBar.Tab</item>
    <item name="actionBarTabStyle">@style/FindMyTrain.ActionBar.Tab</item>
    </style>
    <style name="FindMyTrain.ActionBar.Tab">
    <item name="android:background">@drawable/tab_bar_background</item>
    </style>
    view raw styles.xml hosted with ❤ by GitHub
  2. Next, create the tab_bar_background drawable. This will be a state list drawable, which has different visual appearance depending on whether the tab is selected and/or pressed. In the state list, we’ll reference two other drawables for when the button is selected, and we’ll just use a plain color for the unselected states:
    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android"&gt;
    <item android:state_focused="false" android:state_selected="false" android:state_pressed="false" android:drawable="@color/transparent"/>
    <item android:state_focused="false" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/tab_bar_background_selected"/>
    <item android:state_selected="false" android:state_pressed="true" android:drawable="@color/tab_highlight"/>
    <item android:state_selected="true" android:state_pressed="true" android:drawable="@drawable/tab_bar_background_selected_pressed"/>
    </selector>
  3. We’ll also need to create a colors.xml file to define the two colors we used in the state list drawable:
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    <color name="transparent">#00000000</color>
    <color name="tab_highlight">#ff9ecfbf</color>
    </resources>
    view raw colors.xml hosted with ❤ by GitHub
  4. Now, we need to create the drawables for the different backgrounds. The indicator under the active tab comes from the background drawable, so in our custom version, we’ll include an indicator in the proper color. To do this, I used a hack where I create a layer list with a rectangle shape with a 5dp stroke around the exterior, then offset the rectangle so that the top, left and right sides are outside the bounds of the view, so you only see the bottom line. This works pretty well, but if you know a better way to accomplish this, I’d be very interested to hear about it. In the case of the “pressed” version, the fill color is set on the rectangle to indicate that it is pressed.
    <?xml version="1.0" encoding="utf-8"?>
    <layer-list xmlns:android="http://schemas.android.com/apk/res/android"&gt;
    <item android:top="-5dp" android:left="-5dp" android:right="-5dp">
    <shape android:shape="rectangle">
    <stroke android:color="#ff4ba587" android:width="5dp"/>
    </shape>
    </item>
    </layer-list>
    <?xml version="1.0" encoding="utf-8"?>
    <layer-list xmlns:android="http://schemas.android.com/apk/res/android"&gt;
    <item android:top="-5dp" android:left="-5dp" android:right="-5dp">
    <shape android:shape="rectangle">
    <stroke android:color="#ff4ba587" android:width="5dp"/>
    <solid android:color="@color/tab_highlight"/>
    </shape>
    </item>
    </layer-list>
  5. Now our styles and theme are completely set up, so the last step is to apply the theme in AndroidManifest.xml. In my case, I did this by setting the theme on the application element, but you can also set it per-activity instead:
    <application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/FindMyTrain"
    android:name=".FindMyTrainApplication" >

Once all of this is set up, we run the app and see that the indicator is the right color:

2013-08-27 11.39.33Success!

36 thoughts on “Styling tabs in the Android action bar

  1. nida

    can u please guide me how can i display image on tabs using actionbar while the image should be placed same as test appearing over here my image is displaying outside of tab bar bottom line it should be inside the tab bar bottom line and in center as well

    Reply
  2. Mathieu

    Thanks very much for this help! I’have been looking for it for hours until I found your article. It is very clear, and more important… it works!
    Thanks again and good luck for your next projects ;).

    Reply
  3. Johnson Maung

    Thanks for that.. very big… i have been searching many for changing the bar at the bottom of selected tab… but i got a lot more than this like how to use layer list.. and more .. really thanks.

    Reply
  4. Pete

    Excellent information. Definitely helpful. One suggestion to improve it: add the theme XML from step 1. It required some hunting to pull that together.

    Reply
  5. Eric

    Where can you set the position of the blue line ?
    I’d like a “reversed tab”, one having its indicator on top instead of in the bottom of the view !

    Reply
    1. alwold Post author

      It’s been a while since I played with this, but I think you should be able to modify the layer list XML for the tab bar background in step 4 to move the indicator to the top. Let me know if you get stuck, though.

      Reply
  6. John Blanco

    Some confusion here…the code you have in Step 1 should be in Step 2. And I think a few of us are wondering what’s missing from Step 1. 🙂

    Reply
  7. holoduke51

    nice. much better than the actionbar generator.
    one question though. Do you know if it possible get rid of the left and right margin for the tabs. Also in your example the right tab and the left tab have space between the tab and the outside. The indicator below also does not touch the outer edge.

    Reply
  8. Pingback: Styling ActionBar Tabs | BlogoSfera

  9. Aleksandr

    I made everything as it was described and received a mistake:

    android.content.res.Resources$NotFoundException: File res/drawable/tab_bar_background.xml from drawable resource

    Reply
  10. aloha

    nice post, the problem Im having is when you use more than 5 tabs… they always end up in the visible way so they are quite smaller than ussually and lose some style

    Reply
  11. kerrermanisnl

    Thanks for the tutorial, it worked out great! Had to tweak it here and there a little myself (needed a bit more of an offset for the borders to dissapear) but it worked quite nicely, so thanks!

    Reply
  12. Bahruz

    great tutorial mate. i went all the steps you described in the beginning and this one is the most useful and explaining tutorial i found on action bar styling.was very helpful. thank you very much.

    Reply
  13. QuantumTiger

    This put me in the right direction, but I found that I had an unsightly line around the selected tab on certain devices. Changing the background layer lists to use two shapes with a slight offset fixed this for me. eg

    Reply
    1. alwold Post author

      Yes, I’ve encountered that as well, on certain devices like you said. I also found that if you change the negative offsets to be larger (like an arbitrary value of -15dp or so), it takes care of it.

      Reply
  14. Belidan

    Thanks alot for writing this guide! I looked up so much information about changing the colors of the indicator tabs but none seemed to work for me ( Part of this is missing the necessary knowledge about styling ). But using this as a guide I have successfully changed the look and feel of my tabs.
    Once again, thanks!

    Reply
    1. Aman Khosa

      To get everything blue set your actionBarTabBarStyle to blue and add set the following android:paddingLeft
      android:paddingRight
      both to 0dp

      Reply
  15. Aman Khosa

    Great tutorial helped me out, for anyone trying to remove the (annoying) padding on the left and right add these two lines to your theme

    0dp
    0dp

    Reply
  16. Aman Khosa

    android:paddingLeft
    android:paddingRight

    ok this is weird it wont let me post the actuall lines of code so just change these two values to 0dp in your theme

    Reply

Leave a reply to efe Cancel reply