妙用TabHost

博客园:http://www.cnblogs.com

    农民伯伯: http://www.cnblogs.com/over140

版本

  新浪微博 weibo_10235010.apk

正文

  一、效果图

    

    红色部分是本文要实现的目标。

  二、实现

    maintabs.xml

xml version="1.0" encoding="UTF-8" ?>
< TabHost android:id ="@android:id/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:gravity ="center_vertical" android:layout_gravity ="bottom" android:orientation ="horizontal" android:id ="@id/main_radio" android:background ="@drawable/maintab_toolbar_bg" android:layout_width ="fill_parent" android:layout_height ="wrap_content" >
           
< RadioButton   android:text ="@string/main_home" android:checked ="true" android:id ="@+id/radio_button0" android:layout_marginTop ="2.0dip" android:drawableTop ="@drawable/icon_1_n" style ="@style/main_tab_bottom" />
           
< RadioButton android:id ="@+id/radio_button1" android:layout_marginTop ="2.0dip" android:text ="@string/main_news" android:drawableTop ="@drawable/icon_2_n" style ="@style/main_tab_bottom" />
           
< RadioButton android:id ="@+id/radio_button2" android:layout_marginTop ="2.0dip" android:text ="@string/main_my_info" android:drawableTop ="@drawable/icon_3_n" style ="@style/main_tab_bottom" />
           
< RadioButton android:id ="@+id/radio_button3" android:layout_marginTop ="2.0dip" android:text ="@string/menu_search" android:drawableTop ="@drawable/icon_4_n" style ="@style/main_tab_bottom" />
           
< RadioButton android:id ="@+id/radio_button4" android:layout_marginTop ="2.0dip" android:text ="@string/more" android:drawableTop ="@drawable/icon_5_n" style ="@style/main_tab_bottom" />
       
RadioGroup >
   
LinearLayout >
TabHost >
复制代码

    styles.xml

    < style name ="main_tab_bottom" >
       
< item name ="android:textSize" > @dimen/bottom_tab_font_size 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/home_btn_bg item >
       
< item name ="android:paddingTop" > @dimen/bottom_tab_padding_up item >
       
< item name ="android:layout_width" > fill_parent item >
       
< item name ="android:layout_height" > wrap_content item >
       
< item name ="android:button" > @null item >
       
< item name ="android:singleLine" > true item >
       
< item name ="android:drawablePadding" > @dimen/bottom_tab_padding_drawable item >
       
< item name ="android:layout_weight" > 1.0 item >
   
style >
复制代码

    home_btn_bg.xml

        < selector
         
xmlns:android ="http://schemas.android.com/apk/res/android" >
           
< item android:state_focused ="true" android:state_enabled ="true" android:state_pressed ="false" android:drawable ="@drawable/home_btn_bg_s" />
           
< item android:state_enabled ="true" android:state_pressed ="true" android:drawable ="@drawable/home_btn_bg_s" />
           
< item android:state_enabled ="true" android:state_checked ="true" android:drawable ="@drawable/home_btn_bg_d" />
           
< item android:drawable ="@drawable/transparent" />
       
selector >
复制代码

    代码说明:

        1.  需要注意的是他这里把TabWidget的Visibility设置成了gone!也就是默认难看的风格不见了:,取而代之的是5个带风格的单选按钮.

        2.  注意为单选按钮设置的style,其中最重要的是为其background设置了home_btn_bg.xml,也就是自定义了选中效果。

    Java文件

public class MainTabActivity extends TabActivity implements
        OnCheckedChangeListener {

   
private TabHost mHost;
   
private Intent mMBlogIntent;
   
private Intent mMoreIntent;
   
private Intent mInfoIntent;
   
private Intent mSearchIntent;
   
private Intent mUserInfoIntent;

    @Override
   
protected void onCreate(Bundle savedInstanceState) {
       
super .onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.maintabs);

       
// ~~~~~~~~~~~~ 初始化
        this .mMBlogIntent = new Intent( this , HomeListActivity. class );
       
this .mSearchIntent = new Intent( this , SearchSquareActivity. class );
       
this .mInfoIntent = new Intent( this , MessageGroup. class );
       
this .mUserInfoIntent = new Intent( this , MyInfoActivity. class );
       
this .mMoreIntent = new Intent( this , MoreItemsActivity. class );

        initRadios();
       
        setupIntent();
    }

   
/**
     * 初始化底部按钮
    
*/
   
private void initRadios() {
         ((RadioButton) findViewById(R.id.radio_button0)).setOnCheckedChangeListener(
this );
         ((RadioButton) findViewById(R.id.radio_button1)).setOnCheckedChangeListener(
this );
         ((RadioButton) findViewById(R.id.radio_button2)).setOnCheckedChangeListener(
this );
         ((RadioButton) findViewById(R.id.radio_button3)).setOnCheckedChangeListener(
this );
         ((RadioButton) findViewById(R.id.radio_button4)).setOnCheckedChangeListener(
this );
    }

   
/**
     * 切换模块
    
*/
    @Override
   
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
       
if (isChecked) {
           
switch (buttonView.getId()) {
           
case R.id.radio_button0:
               
this .mHost.setCurrentTabByTag( " mblog_tab " );
               
break ;
           
case R.id.radio_button1:
               
this .mHost.setCurrentTabByTag( " message_tab " );
               
break ;
           
case R.id.radio_button2:
               
this .mHost.setCurrentTabByTag( " userinfo_tab " );
               
break ;
           
case R.id.radio_button3:
               
this .mHost.setCurrentTabByTag( " search_tab " );
               
break ;
           
case R.id.radio_button4:
               
this .mHost.setCurrentTabByTag( " more_tab " );
               
break ;
            }
        }
    }

   
private void setupIntent() {
       
this .mHost = getTabHost();
        TabHost localTabHost
= this .mHost;

        localTabHost.addTab(buildTabSpec(
" mblog_tab " , R.string.main_home,
                R.drawable.icon_1_n,
this .mMBlogIntent));

        localTabHost.addTab(buildTabSpec(
" message_tab " , R.string.main_news,
                R.drawable.icon_2_n,
this .mInfoIntent));

        localTabHost.addTab(buildTabSpec(
" userinfo_tab " , R.string.main_my_info,
                R.drawable.icon_3_n,
this .mUserInfoIntent));

        localTabHost.addTab(buildTabSpec(
" search_tab " , R.string.menu_search,
                R.drawable.icon_4_n,
this .mSearchIntent));

        localTabHost.addTab(buildTabSpec(
" more_tab " , R.string.more,
                R.drawable.icon_5_n,
this .mMoreIntent));

    }

   
private TabHost.TabSpec buildTabSpec(String tag, int resLabel, int resIcon,
           
final Intent content) {
       
return this .mHost
                .newTabSpec(tag)
                .setIndicator(getString(resLabel),
                        getResources().getDrawable(resIcon))
                .setContent(content);
    }
复制代码
 代码说明

      1.  由于TabWidget被隐藏,所以相关的事件也会无效,这里取巧用RadioGroup与RadioButton的特性来处理切换,然后监听事件调用setCurrentTabByTag来切换Activity。

      2.  注意即使TabWidget被隐藏,也要为其设置indicator,否则会保持。

  三、总结

    在这之前如果要做这种效果我恐怕第一时间就会想到用ActivityGroup来做,主要是因为TabHost的TabWidget非常难看,用起来也不方便。其实从源码可以看出,TabActivity也是继承自ActivityGroup,这里结合了单选按钮和TabHost,各取其长,有时间可以专门写一个这样的自定义控件:)

你可能感兴趣的:(妙用TabHost)