4

I have a problem with .setDividerDrawable() only working in versions lower than Ice Cream Sandwich. When I run the emulator the tabs show perfectly, but no divider. When emulating lower versions of Android there is no problem, the dividers show.

I am using this code for creating the TabHost. I have no clue on what it is that makes ICS flinch.

manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.sbl.mytabapp"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="8" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:debuggable="true" >
        <activity
            android:name=".MyTabApp"
            android:label="@string/app_name"
            android:theme="@style/MyTabAppTheme" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".Page1"></activity>
        <activity android:name=".Page2"></activity>
        <activity android:name=".Page3"></activity>
    </application>

</manifest>

MyTabApp.java (R.drawable.divider) refers to this image: enter image description here which is just a 1px wide .jpg file. On ICS it is not shown.

public class MyTabApp extends TabActivity {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        TabHost tabHost = getTabHost();
        TabHost.TabSpec spec;
        Intent intent;

        tabHost.getTabWidget().setDividerDrawable(R.drawable.divider);

        intent = new Intent().setClass(this, Page1.class);
        spec = tabHost.newTabSpec("page1").setIndicator(getLayoutInflater().inflate(R.layout.tab1, null))
                      .setContent(intent);
        tabHost.addTab(spec);

        intent = new Intent().setClass(this, Page2.class);
        spec = tabHost.newTabSpec("page2").setIndicator(getLayoutInflater().inflate(R.layout.tab2, null))
                      .setContent(intent);
        tabHost.addTab(spec);

        intent = new Intent().setClass(this, Page3.class);
        spec = tabHost.newTabSpec("page3").setIndicator(getLayoutInflater().inflate(R.layout.tab3, null))
                      .setContent(intent);
        tabHost.addTab(spec);

        tabHost.setCurrentTab(0);

    } 
}

main.xml

<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabhost"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TabWidget
            android:id="@android:id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </LinearLayout>
</TabHost>

style.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

 <style name="MyTabAppTheme" parent="android:style/Theme"> 
    <item name="android:windowNoTitle">true</item>
 </style> 


 <style name="tablayout" parent="android:style/Theme">
     <item name="android:layout_width">match_parent</item>
     <item name="android:layout_height">match_parent</item>
     <item name="android:height">48dp</item>
     <item name="android:gravity">center</item>
     <item name="android:textColor">@color/font</item>
     <item name="android:background">@drawable/tabselector</item>
 </style>

 <style name="contentlayout" parent="android:style/Theme">
     <item name="android:layout_width">match_parent</item>
     <item name="android:layout_height">match_parent</item>
     <item name="android:textColor">@color/font</item>
     <item name="android:background">@color/background</item>
 </style>
</resources>

tab1.xml, tab2.xml, tab3.xml all contains the same reference style. This is tab 1:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/tab1"
  style="@style/tablayout" />

tabselector.xml The tab drawable backgrounds are 9patch background images.

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Non focused states -->
    <item android:state_focused="false" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/normal" />
    <item android:state_focused="false" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/selected" />

    <!-- Focused states -->
    <item android:state_focused="true" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/normal_focused" />
    <item android:state_focused="true" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/selected_focused" />

    <!-- Pressed -->
    <item android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/normal_pressed" />
    <item android:state_selected="true" android:state_pressed="true" android:drawable="@drawable/selected_pressed" />
</selector> 

How it looks: The tab backgrounds are 9patch background images.
enter image description here

AakashM
  • 62,551
  • 17
  • 151
  • 186
Simon
  • 171
  • 3
  • 13

3 Answers3

4

I had the same problem, I finally ended up adding the separators manually. Adding ImageView between the tabs..

public class MyTabApp extends TabActivity {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        ImageView divider = new ImageView(this);
        divider.setImageResource(R.drawable.tab_seperator);

        TabHost tabHost = getTabHost();
        TabHost.TabSpec spec;
        Intent intent;

        intent = new Intent().setClass(this, Page1.class);
        spec = tabHost.newTabSpec("page1").setIndicator(getLayoutInflater().inflate(R.layout.tab1, null))
                  .setContent(intent);
        tabHost.addTab(spec);

        tabHost.getTabWidget().addView(divider, LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT);

        intent = new Intent().setClass(this, Page2.class);
        spec = tabHost.newTabSpec("page2").setIndicator(getLayoutInflater().inflate(R.layout.tab2, null))
                  .setContent(intent);
        tabHost.addTab(spec);
    } 
}
Johan B
  • 200
  • 2
  • 10
  • I am getting this error, can you help with a fix: E/AndroidRuntime(683): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.sbl.mytabapp/com.sbl.mytabapp.MyTabApp}: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first. – Simon Mar 07 '12 at 00:21
  • 1
    Are you trying to add the same instance of divider multiple times? You can only add an instance of a View (or ImageView) once. If you need multiple divider you need to create multiple instances. – Johan B Mar 07 '12 at 10:07
  • 1
    Spot on. But when I try to add a similar View with a different drawable, the views messes up. I can only press tab1 and tab2. Tab2 and tab3 are both acting like tab2. I think it has something to do with the views. This paste shows my code: [link](http://pastebin.com/z2PDRD8k) Line 21 and 28 is where I've added the separators. – Simon Mar 07 '12 at 14:24
  • I guess that is because index of the views are changed. I actually have onClickListeners on my tabs and calls setCurrrentTab manually, this is I do because for other reasons but it might be why it works for me. (I will paste some code shortly) – Johan B Mar 07 '12 at 14:45
  • 1
    Something like this might work: http://pastebin.com/MHALzj65 (I havn't actually tested the code because it's not exactly how I apply it, but I think it should work.) – Johan B Mar 07 '12 at 15:00
1

you can try this code!

if(Build.VERSION.SDK_INT >= 11)
    mTabHost.getTabWidget().setShowDividers(TabWidget.SHOW_DIVIDER_MIDDLE);
mipe34
  • 5,596
  • 3
  • 26
  • 38
Goutom Roy
  • 91
  • 3
  • 9
1

This behavior seems to be a default behavior in ICS tab themes and needs a work around. Take a look at this answer, specifically the one given by @Janusz, the OP.

Community
  • 1
  • 1
koopaking3
  • 3,375
  • 2
  • 25
  • 36
  • I've been looking at this too, but while this indeed is a solution, it does not mimic the pre ICS tabs 100% – Simon Mar 07 '12 at 00:00