Before we had the action bar and ViewPager
, we had TabHost
and TabWidget
as our means
of displaying tabs. Nowadays, in most cases, using
tabs with a ViewPager
is the preferred option.
However, there may be cases where the classic tabs are a better solution, or you may
have inherited legacy code that still uses TabHost
.
Just as ListActivity
helps one use a ListView
, TabActivity
helps one use a
TabHost
. However, TabActivity
is marked as deprecated. That is largely because
its parent class, ActivityGroup
, is deprecated. While you can still use TabActivity
,
it is no longer recommended. It also is not necessary, as there are ways to use
TabHost
and TabWidget
without using TabActivity
, as will be demonstrated later
in this chapter.
There are a few widgets and containers you need to use in order to set up a tabbed portion of a view:
TabHost
is the overarching container for the tab buttons and tab
contentsTabWidget
implements the row of tab buttons, which contain text
labels and optionally contain iconsFrameLayout
is the container for the tab contents; each tab content is
a child of the FrameLayout
You load contents into that FrameLayout
in one of two ways:
FrameLayout
in a layout XML file you are using for the whole tab setupCuriously, you do not define what goes in the tabs themselves, or how they tie to the
content, in the layout XML file. Instead, you must do that in Java, by creating a series
of TabSpec
objects (obtained via newTabSpec()
on TabHost
), configuring them, then
adding them in sequence to the TabHost
via addTab()
.
The two key methods on TabSpec
are:
setContent()
, where you indicate what goes in the tab content for
this tab, typically the android:id
of the view you want shown when
this tab is selectedsetIndicator()
, where you provide the caption for the tab button
and, in some flavors of this method, supply a Drawable
to represent
the icon for the tabNote that tab “indicators” can actually be views in their own right, if you need more control than a simple label and optional icon.
Also note that you must call setup()
on the TabHost
before configuring any
of these TabSpec
objects. The call to setup()
is not needed if you are using
the TabActivity
base class for your activity.
The sample project can be found in
WidgetCatalog/Tab
.
Layout:
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+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">
<AnalogClock android:id="@+id/tab1"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<Button android:id="@+id/tab2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="A semi-random button"
/>
</FrameLayout>
</LinearLayout>
</TabHost>
Activity:
package com.commonsware.android.tabhost;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TabHost;
public class TabDemo extends Activity {
@Override
public void onCreate(Bundle state) {
super.onCreate(state);
setContentView(R.layout.main);
TabHost tabs=(TabHost)findViewById(R.id.tabhost);
tabs.setup();
TabHost.TabSpec spec=tabs.newTabSpec("tag1");
spec.setContent(R.id.tab1);
spec.setIndicator("Clock");
tabs.addTab(spec);
spec=tabs.newTabSpec("tag2");
spec.setContent(R.id.tab2);
spec.setIndicator("Button");
tabs.addTab(spec);
}
}
Note that ordinarily you would use icons with your tabs, and so the second parameter
to setIndicator()
would be a reference to a drawable resource. This particular sample
skips the icons.
This is what a TabHost
and TabWidget
look like in a few different Android
versions and configurations, based upon the sample app shown above.
Figure 1054: Android 2.3.3
Figure 1055: Android 4.0.3