Android組件必學(xué)之TabHost使用方法詳解
一、TabHost用法
通常情況下我們會(huì)通過繼承TabActivity,調(diào)用getTabHost()獲取TabHost實(shí)例,下面是具體過程。
TabHostActivity.java
public class TabHostActivity extends TabActivity {
private TabHost tabHost;
private Intent certificateIntent;
private Intent feeIntent;
private Intent scoreIntent;
private Intent studyIntent;
private Intent moreIntent;
@Override
publicvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
tabHost = getTabHost();
initIntent();
addSpec();
}
/**
* 初始化各個(gè)tab標(biāo)簽對(duì)應(yīng)的intent
*/
privatevoid initIntent() {
studyIntent = new Intent(this, StudyActivity.class);
scoreIntent = new Intent(this, ScoreActivity.class);
feeIntent = new Intent(this, FeeActivity.class);
certificateIntent = new Intent(this, CertificateActivity.class);
moreIntent = new Intent(this, MoreActivity.class);
}
/**
* 為tabHost添加各個(gè)標(biāo)簽項(xiàng)
*/
privatevoid addSpec() {
tabHost.addTab(this.buildTagSpec("tab_study",
R.string.study_progress,R.drawable.account01, studyIntent));
tabHost.addTab(this.buildTagSpec("tab_score",
R.string.test_score,R.drawable.account02, scoreIntent));
tabHost.addTab(this.buildTagSpec("tab_fee",
R.string.fee_pay,R.drawable.account03, feeIntent));
tabHost.addTab(this.buildTagSpec("tab_certificate", R.string.certificate_grant,R.drawable.accountcertificateIntent));
tabHost.addTab(this.buildTagSpec("tab_more", R.string.more,
R.drawable.account05, moreIntent));
}
/**
* 自定義創(chuàng)建標(biāo)簽項(xiàng)的方法
* @param tagName 標(biāo)簽標(biāo)識(shí)
* @param tagLable 標(biāo)簽文字
* @param icon 標(biāo)簽圖標(biāo)
* @param content 標(biāo)簽對(duì)應(yīng)的內(nèi)容
* @return
*/
private TabHost.TabSpec buildTagSpec(String tagName, int tagLable,
int icon, Intent content) {
returntabHost
.newTabSpec(tagName)
.setIndicator(getResources().getString(tagLable),
getResources().getDrawable(icon)).setContent(content);
}}
運(yùn)行結(jié)果如下圖所示

我們發(fā)現(xiàn)標(biāo)簽位置處于界面上方,但是我們看到的很多應(yīng)用的標(biāo)簽都處于界面底部。
如下圖所示

我們要實(shí)現(xiàn)這種效果只需要將TabActivity的默認(rèn)布局覆蓋即可。新布局只需將標(biāo)簽和標(biāo)簽對(duì)應(yīng)內(nèi)容的相對(duì)位置調(diào)換一下就可以了,這里是用相對(duì)布局將標(biāo)簽對(duì)應(yīng)內(nèi)容的位置放到了標(biāo)簽的上方。不要改動(dòng)id(會(huì)拋異常,提示必須要用指定的id)。不要忘了在onCreate()里設(shè)置新布局將TabActivity的默認(rèn)布局覆蓋。
@Override
publicvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tab);
tabHost = getTabHost();
initIntent();
addSpec();
}
tab.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- TabHost組件id值不可變--> <TabHostxmlns:android=http://schemas.android.com/apk/res/android android:id="@android:id/tabhost" android:layout_height="fill_parent" android:layout_width="fill_parent"> <RelativeLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <!-- TabWidget組件id值不可變--> <TabWidget android:id="@android:id/tabs" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true"> </TabWidget> <!-- FrameLayout布局,id值不可變--> <FrameLayout android:id="@android:id/tabcontent" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_above="@android:id/tabs"> </FrameLayout> </RelativeLayout> </TabHost>
通常在項(xiàng)目中我們都會(huì)有一個(gè)自定義的Activity基類,我們會(huì)讓所有的界面Activity去繼承這個(gè)基類。但是要使用TabHost就要繼承TabActivity,所以我們可以定義兩個(gè)基類,一個(gè)是普通Activity界面的基類,另一個(gè)是包含TabHost界面的基類,讓這個(gè)基類繼承TabActivity即可。
二、TabHost用法—定義Tab標(biāo)簽樣式
第一節(jié)“TabHost用法”中我們介紹了通過TabHost實(shí)現(xiàn)標(biāo)簽頁效果。但是在實(shí)際項(xiàng)目中我們可能更希望定義自己的Tab標(biāo)簽樣式使界面效果更佳。既然不能改變系統(tǒng)的Tab樣式,那么我們可以選擇隱藏系統(tǒng)的東西,使用自己定義的東西(這種方式很好用,以后會(huì)詳細(xì)介紹)。反編譯新浪微博的項(xiàng)目后會(huì)發(fā)現(xiàn),他們?cè)诓季种须[藏了TabWidget即Tab標(biāo)簽而使用一組RadioButton來代替。既然是自己定義的,那肯定是可以自己決定顯示樣式了,那我們的問題也就解決了。
這里我使用的是“TabHost用法—兩種實(shí)現(xiàn)方式”一文種提到的第二種實(shí)現(xiàn)方式,繼承Activity來使用TabHost的。先把代碼貼上來(紅色字體部分為修改或添加的代碼)。
TabHostActivity.java
public class TabHostActivity extends Activity implements
OnCheckedChangeListener {
private TabHost tabHost;
private Intent certificateIntent;
private Intent feeIntent;
private Intent scoreIntent;
private Intent studyIntent;
private Intent moreIntent;
@Override
publicvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tab);
// tabHost = getTabHost();
tabHost = (TabHost) findViewById(R.id.my_tabhost);
LocalActivityManager groupActivity =
new LocalActivityManager(this,false);
groupActivity.dispatchCreate(savedInstanceState);
tabHost.setup(groupActivity);
initIntent();
addSpec();
((RadioGroup) findViewById(R.id.tab_radiogroup))
.setOnCheckedChangeListener(this);
}
/**
* 初始化各個(gè)tab標(biāo)簽對(duì)應(yīng)的intent
*/
privatevoid initIntent() {
studyIntent = new Intent(this, StudyActivity.class);
scoreIntent = new Intent(this, ScoreActivity.class);
feeIntent = new Intent(this, FeeActivity.class);
certificateIntent = new Intent(this, CertificateActivity.class);
moreIntent = new Intent(this, MoreActivity.class);
}
/**
* 為tabHost添加各個(gè)標(biāo)簽項(xiàng)
*/
privatevoid addSpec() {
tabHost.addTab(this.buildTagSpec("tab_study", R.string.study_progress,
R.drawable.account01, studyIntent));
tabHost.addTab(this.buildTagSpec("tab_score", R.string.test_score,
R.drawable.account02, scoreIntent));
tabHost.addTab(this.buildTagSpec("tab_fee", R.string.fee_pay,
R.drawable.account03, feeIntent));
tabHost.addTab(this.buildTagSpec("tab_certificate",
R.string.certificate_grant, R.drawable.account04,
certificateIntent));
tabHost.addTab(this.buildTagSpec("tab_more", R.string.more,
R.drawable.account05, moreIntent));
}
/**
* 自定義創(chuàng)建標(biāo)簽項(xiàng)的方法
* @param tagName 標(biāo)簽標(biāo)識(shí)
* @param tagLable 標(biāo)簽文字
* @param icon 標(biāo)簽圖標(biāo)
* @param content 標(biāo)簽對(duì)應(yīng)的內(nèi)容
* @return
*/
private TabHost.TabSpec buildTagSpec(String tagName, int tagLable,
int icon, Intent content) {
returntabHost
.newTabSpec(tagName)
.setIndicator(getResources().getString(tagLable),
getResources().getDrawable(icon)).setContent(content);
}
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId) {
case R.id.radio_button_study:
tabHost.setCurrentTabByTag("tab_study");
break;
case R.id.radio_button_score:
tabHost.setCurrentTabByTag("tab_score");
break;
case R.id.radio_button_certificate:
tabHost.setCurrentTabByTag("tab_certificate");
break;
case R.id.radio_button_fee:
tabHost.setCurrentTabByTag("tab_fee");
break;
case R.id.radio_button_more:
tabHost.setCurrentTabByTag("tab_more");
break;
}
}
}
tab.xml
<?xml version="1.0" encoding="UTF-8"?>
<TabHost android:id="@+id/my_tabhost" android:layout_width="fill_parent"
android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout android:orientation="vertical"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<FrameLayout android:id="@android:id/tabcontent"
android:layout_width="fill_parent" android:layout_height="0.0dip"
android:layout_weight="1.0" />
<TabWidget android:id="@android:id/tabs" android:visibility="gone"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:layout_weight="0.0" />
<RadioGroup android:id="@+id/tab_radiogroup"
android:background="@drawable/tabs_bg" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:gravity="center_vertical"
android:layout_gravity="bottom" android:orientation="horizontal">
<RadioButton android:id="@+id/radio_button_study"
android:layout_marginTop="2.0dip" android:text="學(xué)習(xí)進(jìn)度"
android:drawableTop="@drawable/account01" style="@style/tab_button_bottom"
android:checked="true" />
<RadioButton android:id="@+id/radio_button_score"
android:layout_marginTop="2.0dip" android:text="考試成績(jī)"
android:drawableTop="@drawable/account02" style="@style/tab_button_bottom" />
<RadioButton android:id="@+id/radio_button_certificate"
android:layout_marginTop="2.0dip" android:text="證書發(fā)放"
android:drawableTop="@drawable/account03" style="@style/tab_button_bottom" />
<RadioButton android:id="@+id/radio_button_fee"
android:layout_marginTop="2.0dip" android:text="費(fèi)用繳納"
android:drawableTop="@drawable/account04" style="@style/tab_button_bottom" />
<RadioButton android:id="@+id/radio_button_more"
android:layout_marginTop="2.0dip" android:text="更多"
android:drawableTop="@drawable/account05" style="@style/tab_button_bottom" />
</RadioGroup>
</LinearLayout>
</TabHost>
styles.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <!-- TabHost標(biāo)簽按鈕樣式 --> <style name="tab_button_bottom"> <item name="android:textSize">12px</item> <item name="android:textColor">#ffffffff</item> <item name="android:ellipsize">marquee</item> <item name="android:gravity">center_horizontal</item> <item name="android:background">@drawable/tab_btn_bg</item> <item name="android:layout_marginTop">2.0dip</item> <item name="android:button">@null</item> <item name="android:paddingTop">6dip</item> <item name="android:drawablePadding">4dip</item> <item name="android:layout_width">fill_parent</item> <item name="android:layout_height">wrap_content</item> <item name="android:layout_weight">1.0</item> <item name="android:singleLine">true</item> </style> <!-- 頁面標(biāo)題LinearLayout樣式 --> <style name="activity_title_background"> <item name="android:background">@drawable/title_background</item> <item name="android:layout_width">fill_parent</item> <item name="android:layout_height">wrap_content</item> <item name="android:layout_alignParentTop">true</item> <item name="android:gravity">center</item> </style> <!-- 界面標(biāo)題TextView樣式 --> <style name="activity_title_text"> <item name="android:textSize">14dip</item> <item name="android:textColor">@drawable/white</item> <item name="android:layout_width">wrap_content</item> <item name="android:layout_height">wrap_content</item> <item name="android:gravity">center</item> </style> </resources>
運(yùn)行結(jié)果如下圖所示

程序重要部分:
1. 紅色字體部分。
2. 布局文件tab.xml,可以看到該布局文件中將TabWidget隱藏(android:visibility="gone")而以一個(gè)RadioGroup取而代之。
3. 為RadioGroup設(shè)置OnCheckedChangeListener監(jiān)聽,通過onCheckedChanged方法對(duì)各個(gè)RadioButton點(diǎn)擊事件的處理完成標(biāo)簽切換。
其實(shí)我當(dāng)初考慮過為什么要用RadioButton而不用普通的Button。后來通過自己做項(xiàng)目,發(fā)現(xiàn)使用RadioGroup有以下優(yōu)點(diǎn):
1.另外就是布局上比較方便易懂,不用再去用LinearLayout等布局去包含Button。
2. 我們可以很方便的獲得當(dāng)前選中的標(biāo)簽,當(dāng)然通過TabHost的tabHost.getCurrentTabTag()和getCurrentTab()也是可以的。
3.設(shè)置監(jiān)聽很方便,只需要為RadioGroup設(shè)置監(jiān)聽就行了,程序中對(duì)應(yīng)的代碼是
((RadioGroup) findViewById(R.id.tab_radiogroup))
.setOnCheckedChangeListener(this);
如果用Button的話我們需要為所有的Button一個(gè)一個(gè)去設(shè)置監(jiān)聽,相對(duì)來說比較麻煩。
4. 或許最重要的一點(diǎn)是因?yàn)镽adioButton本身就支持圖片和文字的上下布局,只需指定圖片和文字是什么就可以了而不需要我們自己去實(shí)現(xiàn)這種布局。
<RadioButton android:id="@+id/radio_button_more" android:layout_marginTop="2.0dip" android:text="更多" android:drawableTop="@drawable/account05" style="@style/tab_button_bottom" />
當(dāng)然如果如果RadioButton不能滿足我們的項(xiàng)目需求,比如我們不需要圖片又不想讓文字靠底部顯示,而是居中顯示,這時(shí)我們就可以用其他組件代替RadioButton。其實(shí)我們可以通過修改或自定義等方式實(shí)現(xiàn)多種漂亮的效果,比如“人人網(wǎng)”手機(jī)客戶端的個(gè)人主頁中Tab標(biāo)簽是可以左右滑動(dòng)的。
原創(chuàng)作者:男人應(yīng)似海
以上就是本文的全部?jī)?nèi)容,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- Android開發(fā)之TabHost選項(xiàng)卡及相關(guān)疑難解決方法
- Android TabHost選項(xiàng)卡標(biāo)簽圖標(biāo)始終不出現(xiàn)的解決方法
- android FragmentTabhost實(shí)現(xiàn)導(dǎo)航分頁
- Android 中 TabHost與ViewPager結(jié)合實(shí)現(xiàn)首頁導(dǎo)航效果
- Android組件TabHost實(shí)現(xiàn)頁面中多個(gè)選項(xiàng)卡切換效果
- Android程序開發(fā)之自定義設(shè)置TabHost,TabWidget樣式
- android TabHost(選項(xiàng)卡)的使用方法
- Android TabHost如何實(shí)現(xiàn)頂部選項(xiàng)卡
相關(guān)文章
Android判斷后臺(tái)服務(wù)是否開啟的兩種方法實(shí)例詳解
這篇文章主要介紹了Android判斷后臺(tái)服務(wù)是否開啟的方法的相關(guān)資料,這里提供了兩種方法及實(shí)例,需要的朋友可以參考下2017-07-07
Android UI實(shí)時(shí)預(yù)覽和編寫的各種技巧
大家好,今天給大家分享的是Android中實(shí)時(shí)預(yù)覽UI和編寫UI的各種技巧,2015-11-11
Android 獲取服務(wù)器與客戶端時(shí)差的實(shí)例代碼
下面小編就為大家分享一篇Android 獲取服務(wù)器與客戶端時(shí)差的實(shí)例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-01-01
幾個(gè)Android編程時(shí)需要注意的 web 問題
這篇文章主要介紹了幾個(gè)Android編程時(shí)需要注意的 web 問題,需要的朋友可以參考下2014-12-12
SDL2和OpenGL使用踩坑筆記經(jīng)驗(yàn)分享
今天小編就為大家分享一篇關(guān)于SDL2和OpenGL使用踩坑筆記經(jīng)驗(yàn)分享,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-12-12
Android開發(fā)實(shí)現(xiàn)圓形圖片功能示例
這篇文章主要介紹了Android開發(fā)實(shí)現(xiàn)圓形圖片功能,涉及Android實(shí)現(xiàn)圓形圖片的界面布局與CirImageView組件相關(guān)使用操作技巧,需要的朋友可以參考下2019-04-04
MPAndroidChart 自定義圖表繪制使用實(shí)例
這篇文章主要為大家介紹了MPAndroidChart 自定義圖表繪制使用實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
android studio 新建項(xiàng)目報(bào)錯(cuò)的解決之路
這篇文章主要介紹了android studio 新建工程報(bào)錯(cuò),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03

