Customizing Tabs in Android

In my previous post I demonstrated using the “out of the box” tabs in an Android application.  While this is useful for a basic layout, you quickly come to the conclusion that, frankly, the tabs are hideous and that you need to exert some level of customization over them.

The short answer is that Android does support a deep level of control over the look and feel of the tabs, however, as part of the long answer, this ability has only existed since API Level 4 (Android 1.6).  While this means that your application cannot target Android 1.5 and below.  This is an acceptable compromise, recent studies have shown that the dominant Android OS version is 2.x.

Our base code will the be the same as the end result from the previous post, I will demonstrate how to take this code and use XML to define what the tab looks like.  Here is our end code, for reference.

   1: public class TabTestActivity extends TabActivity {

   2:     /** Called when the activity is first created. */

   3:     @Override

   4:     public void onCreate(Bundle savedInstanceState) {

   5:         super.onCreate(savedInstanceState);

   6:         setContentView(R.layout.main);

   7:         

   8:         TabHost.TabSpec tab1 = getTabHost().newTabSpec("Hockey")

   9:             .setIndicator("Hockey Scores")

  10:             .setContent(new Intent().setClass(this,

  11:                 HockeyScoresActivity.class));

  12:         

  13:         TabHost.TabSpec tab2 = getTabHost().newTabSpec("Football")

  14:             .setIndicator("Football Scores")

  15:             .setContent(new Intent().setClass(this,

  16:                 FootballScoresActivity.class));

  17:         

  18:         TabHost.TabSpec tab3 = getTabHost().newTabSpec("Golf")

  19:             .setIndicator("Golf Scores")

  20:             .setContent(new Intent().setClass(this,

  21:                 GolfScoresActivity.class));

  22:         

  23:         getTabHost().addTab(tab1);

  24:         getTabHost().addTab(tab2);

  25:         getTabHost().addTab(tab3);

  26:     }

  27: }

Running this code yields the following output:

image

Note: I did change the background color from the previous example

Very unsightly. Lets restructure the the tabs to make them look nicer.  How about this:

image

Looks a lot nicer right? So how did we do this, well I first I added a couple things to our project.  The first was a new XML file to house the layout for each tab, the XML is shown below:

image

As with any layout XML in Android, you can do whatever you like with this, for this example, I am keeping things simple.  We have a simple TextView within a standard LinearLayout view group.

The second thing was an image called “tab_divider.png” (available in the source).  This is used to separate the tabs in the view.

Here is our updated code for the Activity:

   1: public class TabTestActivity extends TabActivity {

   2:     /** Called when the activity is first created. */

   3:     @Override

   4:     public void onCreate(Bundle savedInstanceState) {

   5:         super.onCreate(savedInstanceState);

   6:         setContentView(R.layout.main);

   7:         

   8:         getTabHost().getTabWidget().setDividerDrawable(

   9:             R.drawable.tab_divider);

  10:         

  11:         View content = LayoutInflater.from(this).inflate(

  12:             R.layout.tab_content, null);

  13:         ((TextView)content.findViewById(R.id.lblText))

  14:             .setText("Hockey Scores");

  15:         TabHost.TabSpec tab1 = getTabHost().newTabSpec("Hockey")

  16:             .setIndicator(content)

  17:             .setContent(new Intent().setClass(this,

  18:                 HockeyScoresActivity.class));

  19:         

  20:         content = LayoutInflater.from(this).inflate(

  21:             R.layout.tab_content, null);

  22:         ((TextView)content.findViewById(R.id.lblText)).

  23:             setText("Football Scores");

  24:         TabHost.TabSpec tab2 = getTabHost().newTabSpec("Football")

  25:             .setIndicator(content)

  26:             .setContent(new Intent().setClass(this,

  27:                 FootballScoresActivity.class));

  28:         

  29:         content = LayoutInflater.from(this).inflate(

  30:             R.layout.tab_content, null);

  31:         ((TextView)content.findViewById(R.id.lblText)).

  32:             setText("Golf Scores");

  33:         TabHost.TabSpec tab3 = getTabHost().newTabSpec("Golf")

  34:             .setIndicator(content)

  35:             .setContent(new Intent().setClass(this,

  36:                 GolfScoresActivity.class));

  37:         

  38:         getTabHost().addTab(tab1);

  39:         getTabHost().addTab(tab2);

  40:         getTabHost().addTab(tab3);

  41:     }

  42: }

The first thing I will point is the setting of the divider.  This step is NOT required, however it really adds to the look of the tabs and helps the user separate them, you mileage may very.  This MUST be called at this point, if you do not call it first you will not see your divider.

Ok the important stuff here is the inflated view we are using (R.layout.tab_content) defines the layout of each of the tabs.  You could use “n” views here if you wanted, I simply chose to use the same view for each and update the TextView using findViewById method.  It is required that you re-inflate the view each time you wish to use it. Not doing so will cause you to get errors concerning the parent view.

Once you inflate the view and set the various properties as desired, you call the setIndicator(View view) overload.  This overload is only available in API Level 4 and above (that is Android 1.6).

As you can see, taking this step is very easy and straightforward and allows for an impressive amount of customization.

At this point, you have now completed the process of customizing the look of the tabs.  However, if you run the application you may notice that as you switch between tabs, there is no indicator of which tab is selected.  That will be the subject of the next entry, I will only say at this point that it involves: State-Lists.

http://cid-630ed6f198ebc3a4.office.live.com/embedicon.aspx/Public/TabTest.zip

Advertisement

One thought on “Customizing Tabs in Android

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s