安卓開發筆記——TabHost組件(一)(實現底部菜單導航)


什么是TabHost?

TabHost組件的主要功能是可以進行應用程序分類管理,例如:在用戶使用windows操作系統的時候,經常見到如圖所示的圖形界面。
 
 

TabHost選項卡,說到這個組件,不得不先說一件事情,翻翻谷歌提供給我們的API,我們可以發現這樣的一段話:

它告訴我們,這個組件在安卓4.0之后已經被廢棄了,建議我們新的程序應該使用Fragment組件來代替它。

其實並不出乎意料,使用過TabHost的朋友應該都知道:

1、它的設計違反了Activity單一窗口原則,它可以同時加載多個Activity,然后再它們之間進行來回切換。

2、有個很致命的問題就是當我們點擊別的選項時,按下Back后退鍵,它會使整個應用程序都退出,而不是切換到前一個選項卡,雖然我們可以在主程序里覆寫OnKeyDown這個方法,但這樣就會導致每一次按下Back后退鍵都只能回到第一個選項菜單。

 

但作為開發者,這個具有歷史里程碑的組件,我們還是需要去掌握下,下面給幾張圖來看下今天要實現的效果:

  

 

下面附上代碼(注釋很詳細)

 

實現TabHost有兩種方式:

方式一:直接讓一個Activity程序繼承TabActivity類(通過getTabHost取得實例);

方式二:定義XML布局文件利用findViewById()方法取得TagHost組件,通過setup()方法實例化並進行若干配置;
 
 
下面講解以第二種方式為例,先看下項目結構:
 
1、TabHost主布局文件

activity_main.xml(為了使選項卡顯示在屏幕下方,這里采用了相對布局)

 1 <TabHost xmlns:android="http://schemas.android.com/apk/res/android"
 2     android:id="@+id/mytabhost"
 3     android:layout_width="fill_parent"
 4     android:layout_height="fill_parent">
 5 
 6     <!-- 需要一個布局管理器 -->
 7  
 8     <RelativeLayout
 9         android:layout_width="fill_parent"
10         android:layout_height="fill_parent" 
11         >
12         
13                 <!--
14        由於TabHost是繼承於FrameLayout,所以需要一個FrameLaytout布局(內容頁) ,id
15        必須為tabcontent
16         -->
17 
18         <FrameLayout
19             android:id="@android:id/tabcontent"
20             android:layout_width="fill_parent"
21             android:layout_height="fill_parent" 
22             >
23         </FrameLayout>
24 
25         <!-- TabWidget必須標簽,用來存放tab標簽,且id必須為tabs -->
26 
27         <TabWidget
28             android:id="@android:id/tabs"
29             android:layout_width="fill_parent"
30             android:layout_height="wrap_content"
31             android:background="@drawable/tab_widget_background"
32             android:layout_alignParentBottom="true"
33             >
34         </TabWidget>
35 
36     </RelativeLayout>
37 
38 </TabHost>

TabHost的布局的文件必須遵循下面幾點:

1、所有的用於標簽配置的文件,必須以“<TabHost>”為根節點;

2、為了保證標簽頁和標簽內容顯示正常(例如:標簽提示要放在標簽顯示內容之上)則可以采用一個布局管理器進行布局(例如:LinearLayout,RelativeLayout..)

3、定義一個“<TagWidget>”的標簽,用於表示整個標簽容器,另外在定義此組件ID為“tabs”,表示允許加入多個標簽

4、由於TabHost是FrameLayout的子類,所以要想定義標簽頁內容必須使用FrameLayout布局,並且標簽ID為“tabcontent”
 
 
 
 

 

 
 
至於為什么要遵循這些條件,我們打看下TabHost的源碼就可以發現:
 
 
 
 
 
 
 
 
 
2、每個標簽的布局文件
 
tab_layout.xml
 
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="wrap_content"
 4     android:layout_height="wrap_content"
 5     android:gravity="center_horizontal"
 6      android:background="@drawable/tab_selector"
 7     android:orientation="vertical" >
 8 
 9     <ImageView
10         android:id="@+id/image"
11         android:layout_width="wrap_content"
12         android:layout_height="wrap_content"
13         android:padding="3dp" />
14 
15     <TextView
16         android:id="@+id/title"
17         android:layout_width="wrap_content"
18         android:layout_height="wrap_content" 
19         android:textColor="@android:color/white"/>
20 
21 </LinearLayout>

 

3、一個選擇器,用於美觀效果

tab_selector.xml

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <selector xmlns:android="http://schemas.android.com/apk/res/android" >
 3     <item 
 4         android:state_pressed="true" android:drawable="@drawable/tab_item_p"
 5         ></item>
 6     <item 
 7         android:state_selected="true" android:drawable="@drawable/tab_item_d"
 8         ></item>
 9 
10 </selector>

 

4、跳轉Activity的布局文件(由於基本一致,這里只給出其中一個)

tabactivity.xml

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent" >
 5 
 6     <LinearLayout
 7         android:layout_width="match_parent"
 8         android:layout_height="match_parent"
 9         android:orientation="vertical" >
10 
11 
12         <TextView
13             android:id="@+id/title"
14             android:layout_width="wrap_content"
15             android:layout_height="wrap_content" 
16             android:text="我是界面1"/>
17     </LinearLayout>
18 
19 </RelativeLayout>

 

5、JAVA主代碼
 
 1 package com.example.tabhosttest;
 2 
 3 import android.app.ActivityGroup;
 4 import android.content.Intent;
 5 import android.os.Bundle;
 6 import android.view.View;
 7 import android.widget.ImageView;
 8 import android.widget.TabHost;
 9 import android.widget.TabHost.TabSpec;
10 import android.widget.TextView;
11 
12 public class MainActivity extends ActivityGroup{
13     
14     private TabHost tabHost;//聲明一個TabHost對象
15 
16     //資源文件
17     private Class activitys[]={TabActivity1.class,TabActivity2.class,TabActivity3.class,TabActivity4.class,TabActivity5.class};//跳轉的Activity
18     private String title[]={"首頁","搜索","設置","主題","更多"};//設置菜單的標題
19     private int image[]={R.drawable.tab_icon1,R.drawable.tab_icon2,R.drawable.tab_icon3,R.drawable.tab_icon4,R.drawable.tab_icon5,};//設置菜單
20     
21     @Override
22     protected void onCreate(Bundle savedInstanceState) {
23         super.onCreate(savedInstanceState);
24         setContentView(R.layout.activity_main);
25         initTabView();//初始化tab標簽
26         
27     }
28 
29     private void initTabView() {
30         //實例化tabhost
31         this.tabHost=(TabHost) findViewById(R.id.mytabhost);
32         //由於繼承了ActivityGroup,所以需要在setup方法里加入此參數,若繼承TabActivity則可省略
33         tabHost.setup(this.getLocalActivityManager());
34         
35         //創建標簽
36         for(int i=0;i<activitys.length;i++){
37             //實例化一個view作為tab標簽的布局
38             View view=View.inflate(this, R.layout.tab_layout, null);
39             
40             //設置imageview
41             ImageView imageView=(ImageView) view.findViewById(R.id.image);
42             imageView.setImageDrawable(getResources().getDrawable(image[i]));
43             //設置textview
44             TextView textView=(TextView) view.findViewById(R.id.title);
45             textView.setText(title[i]);
46             //設置跳轉activity
47             Intent intent=new Intent(this, activitys[i]);
48             
49             //載入view對象並設置跳轉的activity
50             TabSpec spec=tabHost.newTabSpec(title[i]).setIndicator(view).setContent(intent);
51             
52             //添加到選項卡
53             tabHost.addTab(spec);
54         }
55         
56     }
57 
58 
59 }

 

這里有個重載方法setIndicator(),這里是用來設置標簽頁:

1、public TabHost.TabSpec setIndicator(CharSequence label)

設置標題,此時無圖標

2、public TabHost.TabSpec setIndicator(CharSequence label, Drawable icon)

設置標題、圖標(這里的圖標可以用getResources().getDrawable(int id))來設置

3、public TabHost.TabSpec setIndicator(View view)

設置自定義view

 

還有個setContent(Intent intent),這里是用來設置標簽內容的,也就是我們要跳轉的Activity

 

由於這里有5個選項卡,因此就有5個Activity,具體內容就看自己需求了,這里就不再給出

記得寫完Activity要在AndroidManifest.xml配置文件中聲明

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 3     package="com.example.tabhosttest"
 4     android:versionCode="1"
 5     android:versionName="1.0" >
 6 
 7     <uses-sdk
 8         android:minSdkVersion="8"
 9         android:targetSdkVersion="21" />
10 
11     <application
12         android:allowBackup="true"
13         android:icon="@drawable/ic_launcher"
14         android:label="@string/app_name"
15         android:theme="@style/AppTheme" >
16         <activity
17             android:name=".MainActivity"
18             android:label="@string/app_name" >
19             <intent-filter>
20                 <action android:name="android.intent.action.MAIN" />
21 
22                 <category android:name="android.intent.category.LAUNCHER" />
23             </intent-filter>
24         </activity>
25         <activity
26             android:name="com.example.tabhosttest.TabActivity1"
27             android:label="@string/app_name" >
28         </activity>
29         <activity
30             android:name="com.example.tabhosttest.TabActivity2"
31             android:label="@string/app_name" >
32         </activity>
33         <activity
34             android:name="com.example.tabhosttest.TabActivity3"
35             android:label="@string/app_name" >
36         </activity>
37         <activity
38             android:name="com.example.tabhosttest.TabActivity4"
39             android:label="@string/app_name" >
40         </activity>
41         <activity
42             android:name="com.example.tabhosttest.TabActivity5"
43             android:label="@string/app_name" >
44         </activity>
45     </application>
46 
47 </manifest>

 

好了,到這里底部導航菜單就實現了,試試吧~

這里再來個不一樣的實現方法,更為簡潔方便《安卓開發復習筆記——TabHost組件(二)(實現底部菜單導航)

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM