天天看點

動态設定TabHost頁籤屬性及自定義TabHost選項Layout

TabHost生成後會向内添加TabSpec以形成選項欄:

如果是繼承的TabActivity類:

tabhost = getTabHost();
tabhost.addTab(tabhost.newTabSpec("1").setIndicator("TAB 1", getResources().getDrawable(R.drawable.icon)).setContent(R.id.text1)); 
tabhost.setCurrentTab(0);
           

如果是直接繼承Activity類:

tabhost = (TabHost) findViewById(R.id.tabhost);
tabhost.setup();
tabhost.addTab(tabhost.newTabSpec("1").setIndicator("TAB 1", getResources().getDrawable(R.drawable.icon)).setContent(R.id.text1)); 
tabhost.setCurrentTab(0);
           

注意加.setup(),否則會有NullPointer的異常

main.xml:

<TabHost android:id="@+id/tabhost" android:layout_width="fill_parent" android:layout_height="wrap_content">
	<LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent">
		<TabWidget android:id="@android:id/tabs" android:layout_width="fill_parent" android:layout_height="fill_parent" />
		<FrameLayout android:id="@android:id/tabcontent" android:layout_width="fill_parent" android:layout_height="fill_parent">
			<TextView android:id="@+id/text1" android:layout_width="wrap_content" android:layout_height="wrap_content" />
		</FrameLayout>
	</LinearLayout>
</TabHost> 
           

注意:TabHost标簽下的TabWidget和FrameLayout的id是固定的,分别為"tabs"和"tabcontent"

----------------------------------------------------------------------------------分割線---------------------------------------------------------------------------------------------

動态更改TabHost的頁籤頭顯示,有兩種方法:一種比較笨而且可控性差(為什麼還要講一會再說),一種比較簡單而且可控性高,我們先說簡單的那一種:

TabHost本身不提供有效的函數支援對頁籤頭的動态更改,但是我們可以通過TabHost的getTabWidget()函數得到頁籤頭的View進而"曲線"更改頁籤頭的屬性:

ImageView iv = (ImageView) tabhost.getTabWidget().getChildAt(targetLocation).findViewById(android.R.id.icon);
TextView tv = (TextView) tabhost.getTabWidget().getChildAt(targetLocation).findViewById(android.R.id.title);
tv.setText("XXXX");
iv.setImageDrawable(getResources().getDrawable(R.drawable.icon));			
           

其中獲得的ImageView即是TabHost的頁籤頭在targetLocation位置的圖檔的View,TextView是對應的文字的View,這樣就可以對它們進行任意的改動了,注意targetLocation從0開始

還有一種比較笨的方法:

就是自定義TabHost頁籤頭的Layout,如下:

tabhost = getTabHost();
RelativeLayout tempLayout = (RelativeLayout) LayoutInflater.from(this).inflate(R.layout.mytab, null);
TextView targetTabLabel = (TextView) tempLayout.findViewById(R.id.tab_text);
targetTabLabel.setText("TAB 1");
tempLayout.removeAllViews();
tabhost.addTab(tabhost.newTabSpec("1").setIndicator(targetTabLabel).setContent(R.id.text1));
           

注意要對tempLayout使用removeAllViews(),否則在将targetTabLabel加入TabHost中時會出現java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.的異常

其中R.layout.mytab來自mytab.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
<TextView android:id="@+id/tab_text"  
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textStyle="bold" 
        android:background="@drawable/selector_img"/>
</RelativeLayout>
           

其中android:text="@drawable/selector_img"指向selector_img.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="false"
	  android:drawable="@drawable/img1">
</item>
<item android:state_selected="true"
      android:drawable="@drawable/img2">
</item>
</selector>
           

點選時使用Selector置換背景圖檔,文字的更改尚未用此方法驗證,這種方法非常繁瑣而且可控性太差,隻能響應選擇事件,且隻能更改2個選項,但是之是以講解這種方法,是因為這裡順便講解了如何自定義TabHost頁籤頭的Layout,如果你想在UI上做出更多的花樣,這個技巧是很有幫助的。