Icon in Tab is not showing up
Solution 1:
Have you tested your app on a device running Ice Cream Sandwich? I noticed recently, that the default TabHost
behaves differently depending on the target device and the android platform version.
Running an app that provides an icon and a text to setIndicator
(as in the source from the question), had the following test result:
- Phone with Android 2.1: both icon and text where shown (Label below the Icon as expected)
- Phone with 4.0.3: The icons didn't show and only the text was visible.
- Tablet running ICS: the tabs where shown with icon and text
As you found out too, replacing the label with an empty string the icons appeared on the Phone - but then the user would need to guess the meaning of the icons. Apart from that: When running this version of the app on the pre ICS phone: The tabs keep their size and leave an empty area below the image.
To change this device driven decision on how much space the tabs should get, I found the solution in this tutorial on how to customize tabs:
First you need to provide your own tab indicator layout ("layout/tab_indicator.xml" in the tutorial) including an ImageView
and a TextView
. Then you tell the TabSpec
to use this via setIndicator
. And voilà: you get the icon and the label on the phone with ICS too.
Here is the important part on how to set up the indicator (this = the current activity):
TabHost.TabSpec spec = this.getTabHost().newTabSpec(tag);
View tabIndicator = LayoutInflater.from(this).inflate(R.layout.tab_indicator, getTabWidget(), false);
((TextView) tabIndicator.findViewById(R.id.title)).setText(label);
((ImageView) tabIndicator.findViewById(R.id.icon)).setImageResource(drawableResourceId);
spec.setIndicator(tabIndicator);
If you like the same look of the tabs on older and newer phones have an additional look here: http://jgilfelt.github.com/android-actionbarstylegenerator/. This page generates images and styles to customize the action bar including the tabs and helped me figure out how the 9-patch background images need to be defined.
Solution 2:
This is a easy way to show the text and icon in ICS. After to setup the Tabhost, I call the next methods:
setTabIcon(mTabHost, 0, R.drawable.ic_tab1); //for Tab 1
setTabIcon(mTabHost, 1, R.drawable.ic_tab2); //for Tab 2
public void setTabIcon(TabHost tabHost, int tabIndex, int iconResource) {
ImageView tabImageView = (ImageView) tabHost.getTabWidget().getChildTabViewAt(tabIndex).findViewById(android.R.id.icon);
tabImageView.setVisibility(View.VISIBLE);
tabImageView.setImageResource(iconResource);
}
If you want a more advanced solution, you need to create a layout like @sunadorer recommend. My recommendation is that you can create your layout using the holo theme layout, search the file on your sdk_dir/platforms/android-14/data/res/layout/tab_indicator_holo.xml.
My advanced solution is the next, you need to create a layout like this:
tab_indicator.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingTop="5dp"
android:paddingBottom="5dp"
style="@android:style/Widget.Holo.Tab">
<ImageView
android:id="@android:id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:visibility="visible" />
<TextView
android:id="@android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
style="@android:style/Widget.Holo.ActionBar.TabText" />
</LinearLayout>
In your activity or fragment, create the next function:
public View createTabIndicator(LayoutInflater inflater, TabHost tabHost, int textResource, int iconResource) {
View tabIndicator = inflater.inflate(R.layout.tab_indicator, tabHost.getTabWidget(), false);
((TextView) tabIndicator.findViewById(android.R.id.title)).setText(textResource);
((ImageView) tabIndicator.findViewById(android.R.id.icon)).setImageResource(iconResource);
return tabIndicator;
}
And finally when you create your tab in your activity or fragment use the next code:
mTabHost.addTab(
mTabHost.newTabSpec("tab1")
.setIndicator(createTabIndicator(inflater, mTabHost, R.string.tab1, R.drawable.ic_tab1))
.setContent(R.id.tab1)
);
I have tested this solution in ICS and works fine.
Good luck :)
Solution 3:
There is another very simple solution for this.
It seems that the issue is in new Holo theme and TabWidget
. So what you should do is define Holo theme in your values-v11
folder but with the old TabWidget
style like this:
<style name="MyAppTheme" parent="@android:style/Theme.Holo.NoActionBar"> <item name="android:tabWidgetStyle">@android:style/Widget.TabWidget</item> </style>
It works for me, hope it helps someone.
Solution 4:
I try the following way to do it and it works fine:
- using setIndicator("TAB") to set text only.
- using setBackgroundDrawable(-) to set icon.
Sample code:
final TabHost tabHost = (TabHost)findViewById(android.R.id.tabhost);
final Resources res = getResources();
int i;
tabHost.setup(); //Call setup() before adding tabs if loading TabHost using findViewById().
TabHost.TabSpec ts = tabHost.newTabSpec("trackinfo");
//ts.setIndicator("", res.getDrawable(R.drawable.icon_trackinfo));
ts.setIndicator("Track Information");
ts.setContent(R.id.tabTrackInfo);
tabHost.addTab(ts);
TabHost.TabSpec ts2 = tabHost.newTabSpec("collection");
//ts2.setIndicator("", res.getDrawable(R.drawable.icon_collection_gray));
ts2.setIndicator("My Collection");
ts2.setContent(R.id.tabMyCollecton);
tabHost.addTab(ts2);
tabHost.setOnTabChangedListener(new OnTabChangeListener(){
@Override
public void onTabChanged(String tabId)
{
if("trackinfo".equals(tabId)) {
//
TabWidget tw = (TabWidget)tabHost.findViewById(android.R.id.tabs);
View tabView = tw.getChildTabViewAt(0);
TextView tv = (TextView)tabView.findViewById(android.R.id.title);
tv.setTextColor(TabColor[0]);
tabView.setBackgroundDrawable(res.getDrawable(R.drawable.icon_selected));
tabView = tw.getChildTabViewAt(1);
tv = (TextView)tabView.findViewById(android.R.id.title);
tv.setTextColor(TabColor[1]);
tabView.setBackgroundDrawable(res.getDrawable(R.drawable.icon_gray));
}
if("collection".equals(tabId)) {
//
TabWidget tw = (TabWidget)tabHost.findViewById(android.R.id.tabs);
View tabView = tw.getChildTabViewAt(0);
TextView tv = (TextView)tabView.findViewById(android.R.id.title);
tv.setTextColor(TabColor[1]);
tabView.setBackgroundDrawable(res.getDrawable(R.drawable.icon_gray));
tabView = tw.getChildTabViewAt(1);
tv = (TextView)tabView.findViewById(android.R.id.title);
tv.setTextColor(TabColor[0]);
tabView.setBackgroundDrawable(res.getDrawable(R.drawable.icon_selected));
}
}}); // END OF tabHost.setOnTabChangedListener
// After Tabs being added
// change font settings
TabWidget tw = (TabWidget)tabHost.findViewById(android.R.id.tabs);
for(i=0;i<2;i++)
{
View tabView = tw.getChildTabViewAt(i);
TextView tv = (TextView)tabView.findViewById(android.R.id.title);
tv.setHeight(25);
tv.setTextColor(TabColor[i]);
tv.setTypeface(Typeface.SANS_SERIF, Typeface.BOLD_ITALIC);
tv.setTextSize(20);
tabView.setBackgroundDrawable(res.getDrawable(TabIcon[i]));
}