这篇文章总结了TabActivity的三种基本用法,具体的例子都取自ApiDemo。
基本知识
要实现多标签的Activity,目标Activity(就是你建立的那个)首先要实现TabActivity类。这样,用户就可以通过getTabHost()方法来获得对应的TabHost对象,从而动态地添加标签。下面给出了标签切换时,如何设定显示区内容的三种方法。
从Layout文件中构造显示区布局
最简单的方法就是,给出Layout文件,然后再用LayoutInflator将其inflate到显示区。由于所有的标签都在同一个Layout文件中定义,因此FrameLayout就是必须的布局了。因为你一次只能显示一个内容。在ApiDemo的第一个例子中,给出的布局文件如下:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:id="@+id/view1"
android:background="@drawable/blue"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/tabs_1_tab_1"/>
<TextView android:id="@+id/view2"
android:background="@drawable/red"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/tabs_1_tab_2"/>
<TextView android:id="@+id/view3"
android:background="@drawable/green"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/tabs_1_tab_3"/>
这个布局一次只能显示一个TextView。这样我们可以通过在setContent中给出其id号来实现。
不过首先要将这个Layout扩充到显示区中去,我们可以通过tabHost.getTabContentView()来获得View的引用,Activity的onCreate的代码如下:
TabHost tabHost = getTabHost();
LayoutInflater.from(this).inflate(R.layout.tabs1, tabHost.getTabContentView(), true);
tabHost.addTab(tabHost.newTabSpec("tab1")
.setIndicator("tab1")
.setContent(R.id.view1));
tabHost.addTab(tabHost.newTabSpec("tab3")
.setIndicator("tab2")
.setContent(R.id.view2));
tabHost.addTab(tabHost.newTabSpec("tab3")
.setIndicator("tab3")
.setContent(R.id.view3));
LayoutInflator的语句首先从当前context构造LayoutInflator的实例,然后将R.layout.tabs1的布局文件(如上)添加到TabContent里面去。
动态构造显示区内容
所谓动态构造,就是当标签被点击时,指定的接口被调用,然后返回要显示的View。这是通过实现接口TabHost.TabContentFactory来获得的。TabHost.TabContentFactory接口提供了createTabContent方法。具体做法如下:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final TabHost tabHost = getTabHost();
tabHost.addTab(tabHost.newTabSpec("tab1")
.setIndicator("tab1", getResources().getDrawable(R.drawable.star_big_on))
.setContent(this));
tabHost.addTab(tabHost.newTabSpec("tab2")
.setIndicator("tab2")
.setContent(this));
tabHost.addTab(tabHost.newTabSpec("tab3")
.setIndicator("tab3")
.setContent(this));
}
/** {@inheritDoc} */
public View createTabContent(String tag) {
final TextView tv = new TextView(this);
tv.setText("Content for tab with tag " + tag);
return tv;
}
由于setContext被设置为this,createTabContent被调用来构造显示区的内容。该函数传入的tag就是newTabSpec时定义的标记。createTabContent会根据tag标记来判断是哪个标签被点击,然后动态构造View并返回。
使用Intent来调用别的Activity
TabActivity最常用的地方就是,通过标签来将多个不同的Activity来组合在一个界面内。而这又是通过Intent来实现的,将Intent实例传入setContent即可。实例如下:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final TabHost tabHost = getTabHost();
tabHost.addTab(tabHost.newTabSpec("tab1")
.setIndicator("list")
.setContent(new Intent(this, List1.class)));
tabHost.addTab(tabHost.newTabSpec("tab2")
.setIndicator("photo list")
.setContent(new Intent(this, List8.class)));
// This tab sets the intent flag so that it is recreated each time
// the tab is clicked.
tabHost.addTab(tabHost.newTabSpec("tab3")
.setIndicator("destroy")
.setContent(new Intent(this, Controls2.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)));
}
ApiDemo的view->tabs给出来三种具体的实例,非常全面。
结语
TabActivity的定制是非常重要,而且常用的,但其基本的使用已经能够满足绝大多数要了。应该说这也是Android开发一个必须掌握的点了。