: Beginning Android

Adding Them Up

Adding Them Up

TabWidget is set up to allow you to easily define tabs at compile time. However, sometimes, you want to add tabs to your activity during runtime. For example, imagine an email client where individual emails get opened in their own tab for easy toggling between messages. In this case, you dont know how many tabs or what their contents will be until runtime, when the user chooses to open a message.

Fortunately, Android also supports adding tabs dynamically at runtime.

Adding tabs dynamically at runtime works much like the compile-time tabs previously shown, except you use a different flavor of setContent(), one that takes a TabHost.TabContentFactory instance. This is just a callback that will be invoked you provide an implementation of createTabContent() and use it to build and return the Lets take a look at an example (Fancy/DynamicTab).

First, here is some layout XML for an activity that sets up the tabs and defines one tab, containing a single button:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TabHost android:id="@+id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TabWidget android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<FrameLayout android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingTop="62px">
<Button android:id="@+id/buttontab"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="A semi-random button"
/>
</FrameLayout>
</TabHost>
</LinearLayout>

What we want to do is add new tabs whenever the button is clicked. That can be accomplished in just a few lines of code:

publicclass DynamicTabDemoextends Activity {
@Override
public voidonCreate (Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
final TabHost tabs = (TabHost)findViewById(R.id.tabhost);
tabs.setup();
TabHost.TabSpec spec = tabs.newTabSpec(buttontab);
spec.setContent(R.id.buttontab);
spec.setIndicator(Button);
tabs.addTab(spec);
tabs.setCurrentTab(0);
Button btn = (Button)tabs.getCurrentView().findViewById(R.id.buttontab);
btn.setOnClickListener(new View.OnClickListener() {
public voidonClick(View view) {
TabHost.TabSpec spec = tabs.newTabSpec(tag1);
spec.setContent(new TabHost.TabContentFactory() {
public ViewcreateTabContent(String tag) {
return(newAnalogClock(DynamicTabDemo.this));
}
});
spec.setIndicator(Clock);
tabs.addTab(spec);
}
});
}
}

In our buttons setOnClickListener() callback, we create a TabHost.TabSpec object and give it an anonymous TabHost.TabContentFactory. The factory, in turn, returns the View to be used for the tab in this case, just an AnalogClock. The logic for constructing the tabs View could be much more elaborate, such as using LayoutInflater to construct a view from layout XML.

In Figure 10-7 you can see that initially, when the activity is launched, we just have the one tab whereas Figure 10-8 shows multiple tabs.


Figure 10-7.The DynamicTab application, with the single initial tab


Figure 10-8.The DynamicTab application, with three dynamically-created tabs


: 0.308. /Cache: 3 / 0