Monday, August 29, 2011

Changing Tab Background Color

At times things in Android are unbelievably easy. Especially if you have Eclipse's autocompletion function turned on. But occasionally you hit a baffling wall. We are currently re-skinning our Android app. Since the UI is nearly completely defined in resources, this has been amazingly easy to do, until an hour or two ago.

The specification sheet supplied to me by our UI guy uses something other than the default background colors in the tabs, both for the active and inactive tab. Anyone who has worked with tabs in Android already knows that they are one of the more clumsily implemented UI patterns. So much so that the Layout Editor can't accurately process them. For those who don't know, in order to create a tabbed layout, you combine a series of activities together into another layout which is called a Tab Host. The definition of the Tab Host is very strict. It must consist of an outer Tab Host with a Linear Layout inside and surrounding Tab Widget with the id of "tabs" and a layout with the id of "tabcontent".

All of the above won't actually render your tabs, you still must use code in the onCreate method of the activity  to add the activities of the tab views to the tab host. If you do everything right, you get a tabbed layout, if not, mostly likely you'll get an exception.

The problem with all of this is that somethings, most notably the background colors, are hard-coded into the tabs. Android will let you change the background color of the tab host in both XML and in code, but neither will actually change anything, nor produce an error. The reason for this is that the tabs are actually child elements of the tab host's tab widget. So changing their grand parent, has no effect on them. But don't worry, changing the tabs while clumsy, is easy to do.

First off, make sure that the activity of the Tab Host implements OnTabChangeListener.


implements OnTabChangeListener


Then within the class declare a couple of private variables to hold references to Tab Host and Tab Widget.


private TabHost tabHost;
private TabWidget tabWidget;

Within the onCreate method set the values for tabHost and tabWidget.


tabHost = getTabHost();
tabWidget = tabHost.getTabWidget();

Then set the tab change listener:



tabHost.setOnTabChangedListener(this);


And finally call the colorTabs method which will initially seed the tabs.

colorTabs();

Anytime the user switches tabs, we will need to set their background colors again. So we have to override the tab changed listener.



@Override
public void onTabChanged(String tabId) {
colorTabs();
}



Finally we get to the colorTabs method. Which simply pulls the colors for the active and inactive tabs from the colors.xml, then sets all of the tabs to the inactive color, before finding the active tab and setting it to the active color.


private void colorTabs() {
int inactiveColor = getResources().getColor(R.color.inactive_tab);
int activeColor = getResources().getColor(R.color.active_tab);

// set the inactive tabs
for (int i = 0; i < tabWidget.getChildCount(); i++) {
tabWidget.getChildAt(i).setBackgroundColor(inactiveColor);
}

// set the active tab
tabWidget.getChildAt(tabHost.getCurrentTab()).setBackgroundColor(activeColor);
}

And that is it. Now you can color your tabs to whatever color makes your UI guys happy.