Sai Geetha started off as a Java Developer and moved on to work as a Solution Architect and an Enterprise Architect. However, as a hobby she continues to don the hats of a Java Developer as well as an Android Developer. She loves to share what she learns with the larger community. In her interest to share her knowledge, she blogs Android tutorials at saigeethamn.blogspot.com and her other technical musings at sageethatechnical.blogspot.com. Sai Geetha is a DZone MVB and is not an employee of DZone and has posted 18 posts at DZone. You can read more from them at their website. View Full User Profile

TabLayout or Tabbed View in Android

08.06.2011
| 4523 views |
  • submit to reddit
This tutorial is about developing a TabLayout  / tabs which is one of the very important ways of providing the UI in Android.  The default Contacts application uses this layout.

For creating a tab Layout, we need to look at 3 new aspects: TabActivity, TabHost and TabWidget.

Let us begin by looking at how we should declare the layout xml.  The root node has to be a TabHost. What is a TabHost and why is it required? It is nothing but a container for the tabbed view we want to create. It provides methods to add the tabs, remove them and to bring focus to a specific tab etc.

Within this, we need to have a two objects: TabWidget and a FrameLayout.

The TabWidget itself does not do much except contain a list of tab labels that exist within the parent TabHost.  Basically it is nothing but a set of labels that the user clicks in order to select a specific tab. The actual content of each tab is to be held by the 2nd object in the TabHost i.e. a FrameLayout. Hence both the TabWidget and FrameLayout need to be present on each tab. And in order to align htme one after another, we embed them into a LinearLayout.

Hence the layout XML would be like this:

<TabHost
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<LinearLayout
android:id="@+id/LinearLayout01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"></TabWidget>
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"></FrameLayout>

</LinearLayout>
</TabHost>

Now, we will move on to the coding of activities for a Tabbed Layout.

In the application, I want to have 3 tabs. So how do I do it?

Each of the tabs can have either a View, launch an activity by passing an intent or create a view dynamically by using TabHost.TabContentFactory. I have chosen to show only activities in all my tabs.

So, how many activities do you think we need? 3? Sorry 4! There needs to be a main or the parent activity that would display the whole tabbed view and one activity in each of the tabs.

Now let us look at developing the main activity. This has to extend the TabActivity.  This is no different from an Activity except for the additional ability to handle multiple embedded activities or views.

So here is the main class declaration:
public class TabLayoutSample extends TabActivity {
Let us see now, how to create the first tab.

First, we need to get a handle to the TabHost that we have declared in the XML layout file, so that we can add tab activities into it. Here is the code for the same:

TabHost tabHost = getTabHost();  // The activity TabHost
Into this TabHost, we need to add the tab. How can we? TabHost provides an inner class called TabSpec that allows you to create a tab, populate its contents and add it as a tab to the TabHost.  See how it is done:

TabHost.TabSpec spec; 

// Create an Intent to launch an Activity for the tab (to be reused)
intent = new Intent().setClass(this, WelcomeActivity.class);

// Initialize a TabSpec for each tab and add it to the TabHost
spec = tabHost.newTabSpec("welcome").setIndicator("Welcome",
res.getDrawable(R.drawable.tab_welcome))
.setContent(intent);
tabHost.addTab(spec);



In the first line above, we are creating a spec variable of type TabSpec. Then we are creating an intent that would be forming the content of the first tab. Then, we associate it with the TabSpec.

Since, each tab should have a tab indicator, content and a tag to keep track of it, it is achieved through setIndicator(..) method. Even the image that should be shown in the tab at the top is set through the same method’s 2nd parameter res.getDrawable(R.Drawable.tab_welcome). What is this and how did I set the image?

This part is a long set of steps but very easy to do. Create two images one in light color and one in dark color. Call them as welcome.png and welcome_sepia.png. Copy them into the /res/drawable-mdpi folder.  The, you need to create a state-list drawable that specifies which image to use for each tab state:

[A StateListDrawable is a drawable object defined in XML that uses a several different images to represent the same graphic, depending on the state of the object. For example, a Button widget can exist in one of several different states (pressed, focused, or neither) and, using a state list drawable, you can provide a different background image for each state.]

So, here is the tab_welcome.xml:
<?xml version="1.0" encoding="UTF-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- When selected, use grey -->
<item android:drawable="@drawable/welcome"
android:state_selected="true" />
<!-- When not selected, use white-->
<item android:drawable="@drawable/welcome_sepia" />
</selector>

This XML is describing which welcome image to show when the tab is selected and which to show when the tab is not selected.  This XML too needs to be created in the same folder - /res/drawable-mdpi.

Once all of this is done, when setIndicator("Welcome",                     res.getDrawable(R.drawable.tab_welcome))is called, the image associated with the tab is shown correctly based on the state.

Then, the last part of the tabSpec call is associating the activity that should be shown in the content of the activity. For this, I have created a new Intent which invokes an Activity – ‘WelcomeActivity.class’.  this implies that the WelcomeActivity.class is already created and available. In this case, it just contains a welcome message to be shown.

Once such a spec is created, I add it to the TabHost through the addtab(…) method of the TabHost. I have repeated the above to show existing “contacts” in the next tab and then the “top links” in the third tab. You can get the complete code for the same here.
References
Published at DZone with permission of Sai Geetha M N, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Gagan Peter replied on Sat, 2012/04/14 - 5:01am

You forgot one important step!

In general Android developers should know this, but be sure to add your new activities to the AndroidManifest.xml file!!! Otherwise you'll get a Forceclose when you attempt to run your app.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.