45

I'm using the following style together with a set of nine patch images to create a red line at the bottom of some Ice Cream Sandwich tabs instead of the standard blue line:

<style name="customTabStyle" parent="@android:style/Widget.Holo.ActionBar.TabBar">
    <item name="android:tabStripLeft">@null</item>
    <item name="android:tabStripRight">@null</item>
    <item name="android:tabStripEnabled">false</item>
    <item name="android:showDividers">none</item>
    <item name="android:measureWithLargestChild">true</item>
    <item name="android:background">@drawable/tab_line</item>
    <item name="android:gravity">center</item>
</style>

<style name="customTabBar" parent="@android:style/Widget.Holo">
    <item name="android:showDividers">middle</item>
    <item name="android:divider">@drawable/divider2</item>
    <item name="android:dividerPadding">0dp</item>
</style>

<style name="LightThemeSelector" parent="android:Theme.Holo.Light">
    <item name="android:actionBarTabStyle">@style/customTabStyle</item>
    <item name="android:actionBarTabBarStyle">@style/customTabBar</item>
</style>

The red line is shown and everyting looks good, except for the divider between the tabs. As you can see inside the green box in the image the line is not drawn below the divider. How do I select a drawable, or a style for this divider?

The android:divider and android:showDividers items are not responsible for the divider between tabs. They only select the divider drawn between the tab icon and the tab title. I hide those dividers because there isn't a title and a divider would look strange.

Screenshot from the resulting tab bar


Update With the answer from Aneal in mind I added a second style customTabBar. The style selects a drawable as a divider. The divider is a solid black line created with the following 9patch drawable:

9patch drawable creating the divider

With this drawable the divider is drawn, but there is also a blank line next to it:

tab bar with dividers

Carl Anderson
  • 3,446
  • 1
  • 25
  • 45
Janusz
  • 187,060
  • 113
  • 301
  • 369
  • The problem there is your nine patch. If you search the SDK for "list_divider_holo_" You'll find all the nine patches used for the ActionBar tab dividers. If you want to make an accurate one, I would use one in the SDK as a template. You could also try to adjust the padding. – adneal Feb 07 '12 at 08:53
  • There is no problem with my nine patch drawable. Using a drawable from the SDK as you suggested gives me the same result. – Janusz Feb 07 '12 at 09:06
  • Hmm. Think of it like this. If you use the default drawables for everything, the dividers line up correctly, therefore, something that you've changed is the culprit here. If it's not the nine patch, then maybe it's your tabs. I don't know, I can't test the drawables you're using and no one else on here can either. If I were you, I'd start checking things off the list to see why they're slightly off center. Check your style and drawables. – adneal Feb 07 '12 at 09:11
  • check this.. this would help to customize the tabs and divider.. http://stackoverflow.com/questions/5799320/android-remove-space-between-tabs-in-tabwidget – Charan Pai Sep 11 '12 at 09:18
  • Hi @Janusz, i have problem with blue underline, i read all tutorial but nothing help, can you explain how you change color? did you do something on selector xml? because even i use your code all background is same because of background in TabBar, I am grateful if help me – Shayan Pourvatan Feb 09 '14 at 08:02
  • You need to create images with a different color. I recommend http://jgilfelt.github.io/android-actionbarstylegenerator/ that site will generate all needed assets for you. – Janusz Feb 09 '14 at 08:19
  • Thanks for your reply, i seen that before, but i don't figure out, thank any way, I try more, – Shayan Pourvatan Feb 09 '14 at 08:24

6 Answers6

51

After removing every style I use I got the following image:

enter image description here

This image also contains the small gaps. Therefore it seems that this is some kind of default behavior.

However I found a way to work around the problem. I set the redline as a standard Background for the whole tabbar. This way the gap appears but nobody can see it because the background, that already contains the line is shown.

I now use the following style for all my activities:

<style name="LightThemeSelector" parent="android:Theme.Holo.Light">
    <item name="android:actionBarTabBarStyle">@style/customTabBar</item>
    <item name="android:actionBarTabStyle">@style/customTabStyle</item>
</style>

This style is used to style each single tab inside the tabbar:

<style name="customTabStyle" parent="@android:style/Widget.Holo.ActionBar.TabView">
    <item name="android:showDividers">none</item>
    <item name="android:measureWithLargestChild">true</item>
    <item name="android:background">@drawable/tab_line</item>
    <item name="android:gravity">center</item>
</style>

To style the whole Tabbar i use the following style:

<style name="customTabBar" parent="@android:style/Widget.Holo.ActionBar.TabBar">
    <item name="android:showDividers">middle</item>
    <item name="android:divider">@drawable/divider</item>
    <item name="android:dividerPadding">0dp</item>
    <item name="android:background">@drawable/tab_unselected</item>
</style>

This style defines my custom divider and also defines the background for the tabbar. As background I directly set the nine patch drawable that is drawn if a tab is not selected. The result of all this is a tabbar with a red underline without any gaps.

enter image description here

Janusz
  • 187,060
  • 113
  • 301
  • 369
22

Here you go.

<style name="YourTheme" parent="@android:style/Theme.Holo.Light">
    <item name="android:actionBarTabBarStyle">@style/Divider</item>
</style>

<style name="Divider" parent="@android:style/Widget.Holo.ActionBar.TabBar">
    <item name="android:divider">@drawable/your_divider_drawable_here</item>
    <item name="android:showDividers">middle</item>
    <item name="android:dividerPadding">12dip</item>
</style>
Janusz
  • 187,060
  • 113
  • 301
  • 369
adneal
  • 30,484
  • 10
  • 122
  • 151
  • What? Just change "@null" to whatever you want. I hid them to make sure it was working when I tested it. That's exactly what you need. Check the answer if you accept it, please. – adneal Feb 07 '12 at 08:16
  • It seems that trying to override any of the attributes of the TabBar style do not work. At least for ActionBarSherlock. – Etienne Lawlor Oct 26 '13 at 07:53
8
<style name="AppTheme" parent="AppBaseTheme">
    <item>......
    </item>
    <item name="android:actionBarDivider">@null</item>

</style>

here @null is for not to provide any divider and if you want to customize your divider than use @drawable/your_divider_image

Devang
  • 91
  • 3
  • 8
6

If you'd like to get rid of dividers you could do just this:

<style name="customTabBar" parent="@android:style/Widget.Holo.ActionBar.TabBar">
    <item name="android:divider">@null</item>
</style>
Kid24
  • 4,401
  • 4
  • 23
  • 19
  • I tried this and didnt work for me. The parent in my case is `parent="@style/Widget.Sherlock.ActionBar.TabBar"` which is an ActionBarSherlock style. – Etienne Lawlor Oct 26 '13 at 07:27
6

Btw. This is caused by huge bug in the ICS in LinerLayout class implementation of android:divider attribute. It was introduced in Honeycomb, broken in ICS and working again in Jelly Bean.

Problem is that when you use android:divider it make small space between it child for place divider, but place divider no into this space, but after it, so it will be overlap by the tab itself and space will stay empty. Very stupid bug. Try to compare LinerLayout source code for release 4.0 and 4.1.

And yes solution is put the delimiter to the background of all tabs and it will be visible only in the gaps between tabs caused by this bug.

ATom
  • 15,960
  • 6
  • 46
  • 50
1

Based on ATom's answer, here's a way to have something resembling dividers in all android versions.

In order to make this work, you don't use any of the native divider methods (because they are broken in some versions). Don't forget removing any code where you set dividers.

The trick is simply setting a very small right margin in the views used for each tab. This way, there will be a small gap where you can see the background (the TabHost). To finish this, you set the background on the TabHost to mimic stretched divider.

Although this trick doesn't work for all possible designs you might want, it works well for many cases like the one I had.

Here's a sample implementation:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    // ...
    //      inflate or create tabHost  in code
    //      call tabHost.setup
    // ...

    TabWidget tabWidget = tabHost.getTabWidget();
    tabWidget.setBackgroundResource(R.drawable.tab_divider);

    // ...  add tabs

    for( int i = 0; tabWidget.getChildCount()-1; i++) {
        View view = tabWidget.getChildAt(i);
        LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) view.getLayoutParams();
        layoutParams.rightMargin = getResources().getDimensionPixelSize(R.dimen.tab_divider_width); //1dp
        view.setLayoutParams(layoutParams);
    }
    return tabHost;
}

Here's a sample tab_divider drawable:

<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
        <solid android:color="@color/divider_color" />
        <stroke android:width="@dimen/tab_divider_vertical_padding" 
                android:color="@color/tab_background_color"/>
</shape>
Community
  • 1
  • 1
Pedro Loureiro
  • 11,436
  • 2
  • 31
  • 37