Android上TabActivity的使用(1)
这篇文章总结了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开发一个必须掌握的点了。