什么是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. <TextView
  12. android:id="@+id/title"
  13. android:layout_width="wrap_content"
  14. android:layout_height="wrap_content"
  15. android:text="我是界面1"/>
  16. </LinearLayout>
  17.  
  18. </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. }

这里有个重载方法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>
 
 
 

Android控件-TabHost(一)的更多相关文章

  1. Android控件-TabHost(二)

    这边再补充一种更为灵活的方法,可以把TabWidget隐藏,用(RadioGroup+RadioButton)来代替,并利用监听器的方式来实现监听点击点击跳转Activity. 在讲解之前,先补充几点 ...

  2. [Android Pro] android控件ListView顶部或者底部也显示分割线

    reference to  :  http://blog.csdn.net/lovexieyuan520/article/details/50846569 在默认的Android控件ListView在 ...

  3. Android控件Gridview实现仿支付宝首页,Fragment底部按钮切换和登录圆形头像

    此案例主要讲的是Android控件Gridview(九宫格)完美实现仿支付宝首页,包含添加和删除功能:Fragment底部按钮切换的效果,包含四个模块,登录页面圆形头像等,一个小项目的初始布局. 效果 ...

  4. Android 控件架构及View、ViewGroup的测量

    附录:示例代码地址 控件在Android开发的过程中是必不可少的,无论是我们在使用系统控件还是自定义的控件.下面我们将讲解一下Android的控件架构,以及如何实现自定义控件. 1.Android控件 ...

  5. Android - 控件android:ems属性

    Android - 控件android:ems属性http://blog.csdn.net/caroline_wendy/article/details/41684255?utm_source=tui ...

  6. Android 控件知识点,

    一.Android控件具有visibility属性,可以取三个值:visible(默认值)可见,invisible(不可见,但仍然占据原有的位置和大小,可以看做是变得透明了),gone(空间不仅不可见 ...

  7. UIAutomator定位Android控件的方法

    UIAutomator各种控件定位的方法. 1. 背景 使用SDK自带的NotePad应用,尝试去获得在NotesList那个Activity里的Menu Options上面的那个Add note菜单 ...

  8. 从Android系统出发,分析Android控件构架

    从Android系统出发,分析Android控件构架 Android中所有的控件追溯到根源,就是View 和ViewGroup,相信这个大家都知道,但是大家也许会不太清楚它们之间的具体关系是什么,在A ...

  9. Android控件系列之RadioButton&RadioGroup(转)

    学习目的: 1.掌握在Android中如何建立RadioGroup和RadioButton 2.掌握RadioGroup的常用属性 3.理解RadioButton和CheckBox的区别 4.掌握Ra ...

随机推荐

  1. python+selenium进行简单验证码获取

    # _*_ coding:utf-8 _*_from PIL import Imagefrom selenium import webdriverimport pytesseractimport ti ...

  2. java 实现顺序结构线性列表

    package com.ncu.list; /** * * 顺序结构线性列表 * * @author liuhao * */ public class SquenceList<T> { p ...

  3. 【BZOJ 1005】[HNOI2008]明明的烦恼(暴力化简法)

    [题目链接]:http://www.lydsy.com/JudgeOnline/problem.php?id=1005 [题意] 中文题 [题解] 一棵节点上标有序号的树会和一个prufer数列唯一对 ...

  4. POJ--1966--Cable TV Network【无向图顶点连通度】

    链接:http://poj.org/problem?id=1966 题意:一个无向图,n个点,m条边,求此图的顶点连通度. 思路:顶点连通度,即最小割点集里的割点数目.一般求无向图顶点连通度的方法是转 ...

  5. 【金阳光測试】基于控件核心技术探讨---Android自己主动化系列(2)---2013年5月

    第一讲分享了下安卓自己主动化一些概况和一些自己主动化框架现状和技术可以解决什么样的问题. 这次课就深入到android世界里面.遨游.翱翔.深入了解自己主动化測试核心技术. 搞过编程开发的同学听到in ...

  6. programming-challenges Shoemaker&#39;s Problem (110405) 题解

    Greedy. 证明: Let's say we have job 1, 2, ..., n, and they have time and fine as t1, f1, t2, f2, ..., ...

  7. bzoj1055: [HAOI2008]玩具取名(dp)

    1055: [HAOI2008]玩具取名 题目:传送门 简要题意: 就是固定四个字母,给出这四个字母分别可以由哪两个字母组成,然后在给你一个字符串,要求把这个字符串还原成原始的四个字母的其中一个. 题 ...

  8. dig linux下的使用

    一般来说linux下查询域名解析有两种选择,nslookup或者dig,而在使用上我觉得dig更加方便顺手. 如果是在debian下的话,只要装上dnsutils这个包就可以使用dig命令了. 最基本 ...

  9. MDNS的漏洞报告——mdns的最大问题是允许广域网的mdns单播查询,这会暴露设备信息,或者被利用用于dns放大攻击

    Vulnerability Note VU#550620 Multicast DNS (mDNS) implementations may respond to unicast queries ori ...

  10. 42.angularJS自定义服务

    转自:https://www.cnblogs.com/best/tag/Angular/ 1. 你可以创建自定义服务,链接到你的模块中: <!DOCTYPE html> <html& ...