在 “標籤頁(TabHost+TabWidget)的使用” 提到預設標籤頁的使用,實際上的應用卻不會使用預設標籤頁,因為介面美觀實在不夠,1個好的應用除了內容外,其 UI 的包裝也是相當重要, 這裡介紹如何使用自訂的標籤頁,如下圖

 
 
 
 
 
 
 
 
 
 
首先來看看 TabHost 套用的佈局檔,如下

  <?xml version="1.0" encoding="utf-8"?>
  <TabHost xmlns:android="http://schemas.android.com/apk/res/android"
      android:id="@android:id/tabhost"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent" >
   
      <LinearLayout
          android:id="@+id/LinearLayout01"
          android:layout_width="fill_parent"
          android:layout_height="fill_parent"
          android:orientation="vertical" >
   
          <!-- Admob add here -->
   
          <LinearLayout
              android:id="@+id/AdLayout"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content" >
          </LinearLayout>
   
          <TabWidget
              android:id="@android:id/tabs"
              android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:visibility="gone" />
   
          <!-- framelayout put here will be buttom -->
   
          <RadioGroup
              android:id="@+id/tab_group"
              android:layout_width="fill_parent"
              android:layout_height="50dp"
              android:layout_gravity="bottom"
              android:background="@drawable/background1"
              android:checkedButton="@+id/tab1"
              android:gravity="center_vertical"
              android:orientation="horizontal" >
   
  <!--             button set null that will remove default radio button -->
   
              <RadioButton
                  android:id="@id/tab1"
                  android:layout_width="fill_parent"
                  android:layout_height="fill_parent"
                  android:layout_marginTop="1.0dip"
                  android:layout_weight="1.0"
                  android:background="@drawable/tab_bg_selector"
                  android:button="@null"
                  android:gravity="center"
                  android:tag="tab1"
                  android:text="消費清單" />
   
              <RadioButton
                  android:id="@+id/tab2"
                  android:layout_width="fill_parent"
                  android:layout_height="fill_parent"
                  android:layout_marginTop="1.0dip"
                  android:layout_weight="1.0"
                  android:background="@drawable/tab_bg_selector"
                  android:button="@null"
                  android:gravity="center"
                  android:text="本日消費" />
   
              <RadioButton
                  android:id="@+id/tab3"
                  android:layout_width="fill_parent"
                  android:layout_height="fill_parent"
                  android:layout_marginTop="1.0dip"
                  android:layout_weight="1.0"
                  android:background="@drawable/tab_bg_selector"
                  android:button="@null"
                  android:gravity="center"
                  android:text="本周消費" />
   
              <RadioButton
                  android:id="@+id/tab4"
                  android:layout_width="fill_parent"
                  android:layout_height="fill_parent"
                  android:layout_marginTop="1.0dip"
                  android:layout_weight="1.0"
                  android:background="@drawable/tab_bg_selector"
                  android:button="@null"
                  android:gravity="center"
                  android:text="本月消費" />
          </RadioGroup>
   
          <!-- framelayout put here will be Top -->
          <FrameLayout
              android:id="@android:id/tabcontent"
              android:layout_width="fill_parent"
              android:layout_height="0.0dip"
              android:layout_weight="1.0" />
      </LinearLayout>
   
  </TabHost>

第 7 行指出使用垂直線性排版
第 8 ~ 11 行為 LinearLayout 的內容
第 13 ~ 19 行為 Admob 的使用,如果沒有 admob 可以忽略
第 21 ~ 25 行為原先的 TabWidget ,注意 25 行我們直接讓它不顯示,也不會作用
第 29 ~ 85 行為取代 TabWidget 的 RadioGroup , 裡面有 4 個 RadioButton 分別在 41, 53, 64, 75 行
第 32 行設定高度
第 33 行設定在畫面底部
第 34 行設定底圖為 background1,為1張 png 圖,它會設定在整個按鈕的下方,注意這張圖的寬高
第 36 行設定其內容按鈕為橫向排列
第 41 ~ 51 行為第 1 個按鈕的設定
第 42 行設定其 id, 注意這個 id 名稱會連結到程式碼中
第 43 ~ 44 行設定尺寸
第 45 行距離上方多 1 dp
第 46 行設定 weight 為 1.0
第 47 行設定按鈕的格式為 xml 檔,注意它決定按鈕顯示的外觀,其內容如下

  <?xml version="1.0" encoding="utf-8"?>
  <selector xmlns:android="http://schemas.android.com/apk/res/android">
   
      <item android:drawable="@drawable/button1" android:state_focused="true"/>
      <item android:drawable="@drawable/button2" android:state_pressed="true"/>
      <item android:drawable="@drawable/button3" android:state_checked="true"/>
   
  </selector>

第 4 行無作用
第 5 行為按鈕被按下的顯示圖片,注意圖片寬高
第 6 行為按鈕被選擇的顯示圖片,注意圖片寬高
第 48 行設定為 null ,以去除預設的按鈕外觀
第 50 行設定其 tag, 注意這個 tag 名稱會連結到程式碼中
第 51 行設定顯示字樣,其他按鈕也是類似的設定
第 88 ~ 92 行為 framelayout 的設定, 注意它也可以放在第 27 行 ,如此按鈕們都會移動到畫面底部
看完  TabHost 套用的佈局檔後,接著來看看其程式碼

  package com.example.helloworld;
   
  import android.app.TabActivity;
  import android.content.Intent;
  import android.os.Bundle;
  import android.view.animation.Animation;
  import android.view.animation.ScaleAnimation;
  import android.widget.LinearLayout;
  import android.widget.RadioButton;
  import android.widget.RadioGroup;
  import android.widget.RadioGroup.OnCheckedChangeListener;
  import android.widget.TabHost;
   
  import com.google.ads.AdRequest;
  import com.google.ads.AdSize;
  import com.google.ads.AdView;
   
  @SuppressWarnings("deprecation")
  public class Table_Flow extends TabActivity{
   
      private RadioGroup tabGroup;
      private RadioButton rb1;
      private RadioButton rb2;
      private RadioButton rb3;
      private RadioButton rb4;
      private TabHost thost;
      public void onCreate(Bundle savedInstanceState){
          super.onCreate(savedInstanceState);
          setContentView(R.layout.table_host);
  //        showAdmob();
          initView();
      }
      void initView(){
          thost = getTabHost();// build tabhost
          tabGroup = (RadioGroup) findViewById(R.id.tab_group);
          rb1 = (RadioButton)findViewById(R.id.tab1);
          rb2 = (RadioButton)findViewById(R.id.tab2);
          rb3 = (RadioButton)findViewById(R.id.tab3);
          rb4 = (RadioButton)findViewById(R.id.tab4);
          Intent inte1 = new Intent(this, Table_widget4.class);
          Intent inte2 = new Intent(this, Table_widget1.class);
          Intent inte3 = new Intent(this, Table_widget2.class);
          Intent inte4 = new Intent(this, Table_widget3.class);
          thost.addTab(thost.newTabSpec("TAB1").setIndicator("tab1").setContent(inte1));
          thost.addTab(thost.newTabSpec("TAB4").setIndicator("tab4").setContent(inte2));
          thost.addTab(thost.newTabSpec("TAB2").setIndicator("tab2").setContent(inte3));
          thost.addTab(thost.newTabSpec("TAB3").setIndicator("tab3").setContent(inte4));
          tabGroup.setOnCheckedChangeListener(new    OnTabChangeListener());
   
      }
       private class OnTabChangeListener implements OnCheckedChangeListener {
   
              @Override
              public void onCheckedChanged(RadioGroup group, int id) {
                  // TODO Auto-generated method stub
                  //button anim
                  Animation scalybig = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f);
                  scalybig.setDuration(500);
                  switch(id){
                  case R.id.tab1:
                      thost.setCurrentTabByTag("TAB1");
                      rb1.startAnimation(scalybig);
                      break;
                  case R.id.tab2:
                      thost.setCurrentTabByTag("TAB2");
                      rb2.startAnimation(scalybig);
                      break;
                  case R.id.tab3:
                      thost.setCurrentTabByTag("TAB3");
                      rb3.startAnimation(scalybig);
                      break;
                  case R.id.tab4:
                      thost.setCurrentTabByTag("TAB4");
                      rb4.startAnimation(scalybig);
   
                      break;
                  }
              }
       }
      void showAdmob(){
      AdView adView;
  //        Create the adView
         adView = new AdView(this, AdSize.BANNER, "a150189a3abeb1a");
         LinearLayout layout = (LinearLayout)findViewById(R.id.AdLayout);
         layout.addView(adView);
         adView.loadAd(new AdRequest());
      }
  }
   
   

事實上內容也沒有太大的改變,只是加入 RadioGroup
第 34 行套用上述的佈局檔
第 36 行為 Admob 的使用,目前不用
第 46 行取得 RadioGroup, 注意 id 要對應 xml 中的設定
第 48 ~ 51 行取得 4 個按鈕, 我針對按鈕有做點選後的動畫
第 53 ~ 56 行設定 4 個 Intent
第 58 ~ 61 行設定 4 個按鈕對應的內容, 注意 setIndicator(“”) 和 setContent(),其傳入參數必須對應 xml 中的設定
第 64 行設定按鈕們的監聽器,其內容在 68 ~ 105 行
第 71 行覆寫 onCheckedChanged 方法
第 75 ~ 76 行為按鈕被按下時播放的動畫
第 79 ~ 101 行為按鈕按下切換的方法,注意 case 對應的 id 和 setCurrentTabByTag 的 id 必須符合