Android组件必学之TabHost使用方法详解

一、TabHost用法
通常情况下我们会通过继承TabActivity,调用getTabHost()获取TabHost实例,下面是具体过程。
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();
 }
 /**
  * 初始化各个tab标签对应的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添加各个标签项
  */
 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));
 }
 /**
  * 自定义创建标签项的方法
  * @param tagName 标签标识
  * @param tagLable 标签文字
  * @param icon 标签图标
  * @param content 标签对应的内容
  * @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);
 }}

运行结果如下图所示

我们发现标签位置处于界面上方,但是我们看到的很多应用的标签都处于界面底部。
如下图所示

我们要实现这种效果只需要将TabActivity的默认布局覆盖即可。新布局只需将标签和标签对应内容的相对位置调换一下就可以了,这里是用相对布局将标签对应内容的位置放到了标签的上方。不要改动id(会抛异常,提示必须要用指定的id)。不要忘了在onCreate()里设置新布局将TabActivity的默认布局覆盖。

 @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>

通常在项目中我们都会有一个自定义的Activity基类,我们会让所有的界面Activity去继承这个基类。但是要使用TabHost就要继承TabActivity,所以我们可以定义两个基类,一个是普通Activity界面的基类,另一个是包含TabHost界面的基类,让这个基类继承TabActivity即可。
二、TabHost用法—定义Tab标签样式
第一节“TabHost用法”中我们介绍了通过TabHost实现标签页效果。但是在实际项目中我们可能更希望定义自己的Tab标签样式使界面效果更佳。既然不能改变系统的Tab样式,那么我们可以选择隐藏系统的东西,使用自己定义的东西(这种方式很好用,以后会详细介绍)。反编译新浪微博的项目后会发现,他们在布局中隐藏了TabWidget即Tab标签而使用一组RadioButton来代替。既然是自己定义的,那肯定是可以自己决定显示样式了,那我们的问题也就解决了。

这里我使用的是“TabHost用法—两种实现方式”一文种提到的第二种实现方式,继承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);

 }

 /**
  * 初始化各个tab标签对应的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添加各个标签项
  */
 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));
 }

 /**
  * 自定义创建标签项的方法
  * @param tagName 标签标识
  * @param tagLable 标签文字
  * @param icon 标签图标
  * @param content 标签对应的内容
  * @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="学习进度"
    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="考试成绩"
    android:drawableTop="@drawable/account02" style="@style/tab_button_bottom" />
   <RadioButton android:id="@+id/radio_button_certificate"
    android:layout_marginTop="2.0dip" android:text="证书发放"
    android:drawableTop="@drawable/account03" style="@style/tab_button_bottom" />
   <RadioButton android:id="@+id/radio_button_fee"
    android:layout_marginTop="2.0dip" android:text="费用缴纳"
    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标签按钮样式 -->
 <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>

 <!-- 页面标题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>

 <!-- 界面标题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>

运行结果如下图所示

程序重要部分:
1.  红色字体部分。
2.  布局文件tab.xml,可以看到该布局文件中将TabWidget隐藏(android:visibility="gone")而以一个RadioGroup取而代之。
3.  为RadioGroup设置OnCheckedChangeListener监听,通过onCheckedChanged方法对各个RadioButton点击事件的处理完成标签切换。

其实我当初考虑过为什么要用RadioButton而不用普通的Button。后来通过自己做项目,发现使用RadioGroup有以下优点
1.另外就是布局上比较方便易懂,不用再去用LinearLayout等布局去包含Button。
2. 我们可以很方便的获得当前选中的标签,当然通过TabHost的tabHost.getCurrentTabTag()和getCurrentTab()也是可以的。
3.设置监听很方便,只需要为RadioGroup设置监听就行了,程序中对应的代码是

((RadioGroup) findViewById(R.id.tab_radiogroup))
       .setOnCheckedChangeListener(this);

如果用Button的话我们需要为所有的Button一个一个去设置监听,相对来说比较麻烦。
4.  或许最重要的一点是因为RadioButton本身就支持图片和文字的上下布局,只需指定图片和文字是什么就可以了而不需要我们自己去实现这种布局。

<RadioButton android:id="@+id/radio_button_more"
   android:layout_marginTop="2.0dip"
android:text="更多"
   android:drawableTop="@drawable/account05"
   style="@style/tab_button_bottom" />

当然如果如果RadioButton不能满足我们的项目需求,比如我们不需要图片又不想让文字靠底部显示,而是居中显示,这时我们就可以用其他组件代替RadioButton。其实我们可以通过修改或自定义等方式实现多种漂亮的效果,比如“人人网”手机客户端的个人主页中Tab标签是可以左右滑动的。

原创作者:男人应似海

以上就是本文的全部内容,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Android Tabhost使用方法详解

    Android 实现tab视图有2种方法,一种是在布局页面中定义<tabhost>标签,另一种就是继承tabactivity.但是我比较喜欢第二种方式,应为如果页面比较复杂的话你的XML文件会写得比较庞大,用第二种方式XML页面相对要简洁得多. 下面是我的XML源码: <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="ver

  • 详解Android TabHost的多种实现方法 附源码下载

    最近仔细研究了下TabHost,主要是为了实现微信底部导航栏的功能,最后也给出一个文章链接,大家不要着急 正文: TabHost的实现分为两种,一个是不继承TabActivity,一个是继承自TabActivity:当然了选用继承自TabActivity的话就相对容易一些,下面来看看分别是怎样来实现的吧. 方法一.定义tabhost:不用继承TabActivity  1.布局文件:activity_main.xml <LinearLayout xmlns:android="http://s

  • android中TabHost的图标(48×48)和文字叠加解决方法

    开发过程中,有时候图标稍微大点,比如48×48的时候,文字就会和图标叠加起来,解决方法如下: 复制代码 代码如下: TabWidget tw = tabHost.getTabWidget(); for (int i = 0; i < tw.getChildCount(); i++) {     TextView tv=(TextView)tw.getChildAt(i).findViewById(android.R.id.title);     ImageView iv=(ImageView)t

  • Android组件TabHost实现页面中多个选项卡切换效果

    TabHost组件可以在界面中存放多个选项卡, 很多软件都使用了改组件进行设计. 一.基础知识 TabWidget : 该组件就是TabHost标签页中上部 或者 下部的按钮, 可以点击按钮切换选项卡; TabSpec : 代表了选项卡界面, 添加一个TabSpec即可添加到TabHost中; -- 创建选项卡 : newTabSpec(String tag), 创建一个选项卡; -- 添加选项卡 : addTab(tabSpec); 二.实例讲解 TabHost的基本使用,主要是layout的

  • Android入门之TabHost与TabWidget实例解析

    本文实例介绍的是Android的Tab控件,Tab控件可以达到分页的效果,让一个屏幕的内容尽量丰富,当然也会增加开发的复杂程度,在有必要的时候再使用.Android的Tab控件使用起来有点奇怪,必须包含和按照以下的顺序: TabHost控件->TabWidget(必须命名为tabs)->FrameLayout(必须命名为tabcontent). 先来贴出本例运行的截图: main.xml的源码如下: <?xml version="1.0" encoding="

  • Android控件之TabHost用法实例分析

    本文实例讲述了Android控件之TabHost用法.分享给大家供大家参考.具体如下: 以下通过TabHost实现android选项卡. main.xml布局文件: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width=

  • Android程序开发之自定义设置TabHost,TabWidget样式

    先看效果: 京东商城底部菜单栏 新浪微博底部菜单栏 本次学习效果图: 第一,主布局文件(启动页main.xml,位于res/layout目录下)代码 <?xml version="." encoding="utf-"?> <TabHost xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_paren

  • android 选项卡(TabHost)如何放置在屏幕的底部

    今天写Tab的时候由于TAB的跳转问题去查资料,倒反而发现更有趣的问题,就是如何将TAB放置在屏幕的底端. 复制代码 代码如下: <?xml version="1.0" encoding="utf-8"?> <TabHost xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/tabhost" a

  • Android中使用TabHost 与 Fragment 制作页面切换效果

    三个标签页置于顶端 效果图: 在文件BoardTabHost.java中定义页面切换的效果:切换页面时,当前页面滑出,目标页面滑入.这是2个不同的动画设定动画时要区分对待 import android.content.Context; import android.util.AttributeSet; import android.view.animation.Animation; import android.view.animation.TranslateAnimation; import

  • android TabHost(选项卡)的使用方法

    首先,定义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_p

随机推荐