這篇文章總結了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開發一個必須掌握的點了。