本文结合源代码和实例来说明TabHost的用法。

使用TabHost 可以在一个屏幕间进行不同版面的切换,例如android自带的拨号应用,截图:

查看tabhost的源代码,主要实例变量有:

private TabWidget mTabWidget;
    private FrameLayout mTabContent;
    private List<TabSpec> mTabSpecs
   也就是说我们的tabhost必须有这三个东西,所以我们的.xml文件就会有规定:继续查看源代码:

if (mTabWidget == null) {
            throw new RuntimeException(
                    "Your TabHost must have a TabWidget whose id attribute is 'android.R.id.tabs'");
        }

mTabContent = (FrameLayout) findViewById(com.android.internal.R.id.tabcontent);
        if (mTabContent == null) {
            throw new RuntimeException(
                    "Your TabHost must have a FrameLayout whose id attribute is 'android.R.id.tabcontent'");
        }
     也就是说我们的.xml文件需要TabWidget和FrameLayout标签。

接下来构建我们自己的tab实例:

有两种方式可以实现:
      一种是继承TabActivity 类,可以使用android的自己内部定义好的.xml资源文件作容器文件。也就是在我们的代码中使用getTabHost(); , 而相应的后台源码是这样的:

this.setContentView(com.android.internal.R.layout.tab_content);
       在系统的资源文件中可以看见这个layout

有了容器,然后我们就需要我们为每个tab分配内容,当然要可以是如何类型的标签:
      例如我们构建一下.xml文件
  首先tab1.xml 是一个LinearLayout布局

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/LinearLayout01" android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    <TextView android:text="tab1 with linear layout"
        android:id="@+id/TextView01" android:layout_width="wrap_content"
        android:layout_height="wrap_content">
    </TextView>
</LinearLayout>

然后是tab2.xml是一个FrameLayout布局

<?xml version="1.0" encoding="utf-8"?>
    <FrameLayout  xmlns:android="http://schemas.android.com/apk/res/android"
   
    android:id="@+id/FrameLayout02"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <LinearLayout android:id="@+id/LinearLayout02"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
            <TextView android:text="tab2"
                android:id="@+id/TextView01" android:layout_width="wrap_content"
                android:layout_height="wrap_content">
            </TextView>
        </LinearLayout>
       
    </FrameLayout>
接着要注册这两个FrameLayout为tabhost的Content,也就是接下来的代码:

LayoutInflater inflater_tab1 = LayoutInflater.from(this);  
        inflater_tab1.inflate(R.layout.tab1, mTabHost.getTabContentView()); 
        inflater_tab1.inflate(R.layout.tab2, mTabHost.getTabContentView());
 
然后需要构建前面说的tabhost的第三个实例变量对应得内容,源代码中是这样的:

private List<TabSpec> mTabSpecs = new ArrayList<TabSpec>(2);
 初始化是两个tab的空间然后会自动扩展:
好 我们构建我们的tabspec:

mTabHost.addTab(mTabHost.newTabSpec("tab_test1").setIndicator("TAB 11").setContent(R.id.LinearLayout01)); 
        mTabHost.addTab(mTabHost.newTabSpec("tab_test1").setIndicator("TAB 11").setContent(R.id.FrameLayout02));

也就是把我们的2个layout作为他的content,当然FrameLayout中可以有其他的布局,来放我的组件。
我们不需要在代码里面设置setContentView();因为getTabHost(); 这个方法调用后就已经设置了,源代码:

if (mTabHost == null) {
            this.setContentView(com.android.internal.R.layout.tab_content);
        }
也就是把系统的tab_content当做view设置。
运行后如下:
 
完整代码:

TabHost mTabHost = getTabHost();
        LayoutInflater inflater_tab1 = LayoutInflater.from(this);  
        inflater_tab1.inflate(R.layout.tab1, mTabHost.getTabContentView()); 
        inflater_tab1.inflate(R.layout.tab2, mTabHost.getTabContentView());  
        mTabHost.addTab(mTabHost.newTabSpec("tab_test1").setIndicator("TAB 11").setContent(R.id.LinearLayout01)); 
        mTabHost.addTab(mTabHost.newTabSpec("tab_test1").setIndicator("TAB 11").setContent(R.id.FrameLayout02));

还有一种就是定义我们自己的tabhost:不用继承TabActivity

首先建立我们自己的.xml文件,当然要包含Tabhost,TabWidget,FrameLayout,着3个标签:

<?xml version="1.0" encoding="utf-8"?> 
<TabHost xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/tabhost" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 
    <LinearLayout 
        android:orientation="vertical" 
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent"> 
        <TabWidget 
            android:id="@android:id/tabs" 
            android:layout_width="fill_parent" 
            android:layout_height="wrap_content" /> 
        <FrameLayout 
            android:id="@android:id/tabcontent" 
            android:layout_width="fill_parent" 
            android:layout_height="fill_parent"> 
            
        </FrameLayout> 
    </LinearLayout> 
</TabHost>

注意的是:除了tabhost的id可以自定义外,其他的必须使用系统的id,为什么后面说,
       当然我们可以在FrameLayout里面添加view来作为tab的内容只需要在create tabspce时候添加就可以了,我们为了把每个tab的内容分开我们依然使用前面用到的两个tab xml文件
 java代码:
      获取TabHost 通过findviewbyid,

setContentView(R.layout.main);  
        TabHost mTabHost = (TabHost)findViewById(R.id.tabhost);
    接下来很重要的一步是要使用TabHost.setup();
     作用是来初始化我们的TabHost容器:
    源代码是这样说的:

<p>Call setup() before adding tabs if loading TabHost using findViewById(). <i><b>However</i></b>: You do
      * not need to call setup() after getTabHost() in {@link android.app.TabActivity TabActivity}.
  也就是说通过findviewbyid,方法获得tabhost必须setup 而通过getTabHost则不用。
  setup干什么呢:源代码

mTabWidget = (TabWidget) findViewById(com.android.internal.R.id.tabs);
        if (mTabWidget == null) {
            throw new RuntimeException(
                    "Your TabHost must have a TabWidget whose id attribute is 'android.R.id.tabs'");
        }

mTabContent = (FrameLayout) findViewById(com.android.internal.R.id.tabcontent);
        if (mTabContent == null) {
            throw new RuntimeException(
                    "Your TabHost must have a FrameLayout whose id attribute is 'android.R.id.tabcontent'");
        }
   他主要是初始化了tabhost的两个实例变量,这里也回答了为什么我们的id必须使用系统定义的id的原因
  接下来工作就和前面相同了:

LayoutInflater inflater_tab1 = LayoutInflater.from(this);  
        inflater_tab1.inflate(R.layout.tab1, mTabHost.getTabContentView()); 
        inflater_tab1.inflate(R.layout.tab2, mTabHost.getTabContentView());
        mTabHost.addTab(mTabHost.newTabSpec("tab_test1").setIndicator("TAB a").setContent(R.id.LinearLayout01));  
        mTabHost.addTab(mTabHost.newTabSpec("tab_test2").setIndicator("TAB b").setContent(R.id.FrameLayout02));

完整代码:

setContentView(R.layout.main);  
        TabHost mTabHost = (TabHost)findViewById(R.id.tabhost);
        mTabHost.setup();
        LayoutInflater inflater_tab1 = LayoutInflater.from(this);  
        inflater_tab1.inflate(R.layout.tab1, mTabHost.getTabContentView()); 
        inflater_tab1.inflate(R.layout.tab2, mTabHost.getTabContentView());
        mTabHost.addTab(mTabHost.newTabSpec("tab_test1").setIndicator("TAB a").setContent(R.id.LinearLayout01));  
        mTabHost.addTab(mTabHost.newTabSpec("tab_test2").setIndicator("TAB b").setContent(R.id.FrameLayout02));

运行结果同上。 如有问题欢迎提出。

转载请说明出处。。。

加上源代码,有用了可以下载下:/Files/freeman1984/atab.rar

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/lastsweetop/archive/2010/05/07/5566200.aspx

转载于:https://blog.51cto.com/5282981/934050

结合源码讲解Tabost相关推荐

  1. C++简介源码讲解精辟版,C++入门级C++学习,C++与C的区别值得知晓

    C++简介源码讲解精辟版,C++入门级C++学习,C++与C的区别值得知晓 C语言和C++基础区别 C++标准输入和输出 命名空 1.命名空间的定义 : namespace 标识符{ } 例:name ...

  2. ORB特征点提取与均匀化——ORBSLAM2源码讲解(一)

    文章目录 前言 一.基础知识 二.ORB特征均匀化策略对性能的影响 三.ORB特征金字塔 四.ORB提取扩展图像 五.ORB特征均匀化 总结 前言 本博客结合哔哩大学视频ORBSLAM2[ORBSLA ...

  3. 顾客信息表mysql_Qt5.5.0使用mysql编撰小软件源码讲解-顾客信息登记表_mysql

    Qt5.5.0使用mysql编写小软件源码讲解---顾客信息登记表 Qt5.5.0使用mysql编写小软件源码讲解---顾客信息登记表 一个个人觉得比较简单小巧的软件. 下面就如何编写如何发布打包来介 ...

  4. Oriented Fast神奇高效的代码实现方式——ORBSLAM2源码讲解(二)

    文章目录 前言 一.基础知识 二.灰度质心法原理 三.UMAX 四.IC_Angle如何做加速运算 总结 前言 本博客结合哔哩大学视频ORBSLAM2[ORBSLAM2源码讲解专题一]ORB特征点提取 ...

  5. 27.串口通信实验源码讲解

    串口通信实验源码讲解 笔记基于正点原子官方视频 视频连接https://www.bilibili.com/video/BV1Wx411d7wT?p=71&spm_id_from=333.100 ...

  6. 双目相机标定OpenCV源码讲解

    双目相机标定OpenCV源码讲解 背景介绍 所述内容 参考资料 摄像机标定部分代码 代码思路 代码中的其他函数 找角点&求内参 求外参 求矫正映射矩阵 后记 背景介绍 暑假接近两个月的时间做了 ...

  7. android飞信短信箱程序源码讲解

    android飞信短信箱程序源码讲解! 一.程序演示 图1.进入程序后的第1页面,头部的新消息提示在任意页面都会弹出. 图2.未读消息数量提示,任意页面. 图3.点击新建短信,(或者会话中的转发选项) ...

  8. 讲解java源码_Java学习之Java源码讲解

    关于Java中源码的学习,是不少同学头疼的知识点.本文整理了JAVA源码学习的八大要点,分别是基础知识.面向对象.异常处理.集合.综合类核心代码.JAVA8新特性.Input/Output和Java小 ...

  9. OpenCV SIFT源码讲解——代码逻辑宏观窥探

    OpenCV SIFT源码讲解--代码逻辑宏观窥探 一.暴露在外的接口:SIFT 二.隐藏在SIFT背后的本质:SIFT_Impl 三.使用sift算法全流程 一.暴露在外的接口:SIFT 一般来说, ...

最新文章

  1. 802.1x 客户端获取ip过程 很详细
  2. 黑马程序员_java异常处理机制
  3. 条件概率 and 条件概率的链式法则 and 期望、方差和协方差
  4. spring mvc学习(60):ssm项目整合
  5. 数据分析案例:亚洲国家人口数据计算
  6. poj1064 二分搜索 挑战程序设计竞赛
  7. Linux 文件内容替换命令
  8. 理解伪元素:before和:after
  9. 数据库系统工程师考点
  10. hadoop 空间配置
  11. 如何在网上下载自己需要的资源
  12. 如何获取div中的value值
  13. 正则表达式与文件格式处理-Linux(笔记)
  14. markdown: 欢迎使用马克飞象
  15. 小丁带你走进git世界一-git简单配置
  16. P2394 yyy loves Chemistry I
  17. 华为运营商级路由器配置示例 | 配置OptionB方式跨域BGP VPLS示例(ASBR兼做PE)
  18. 降低PNG图片存储大小方法、图片压缩方法
  19. 查词app android教程,英语查单词app哪个好_查单词app推荐_专门查单词的app
  20. 7-114 用if-else语句编程百分制成绩转换为五分制成绩

热门文章

  1. C++_类和对象_C++运算符重载_左移运算符重载_链式编程_实现直接打印对象---C++语言工作笔记056
  2. C++_跳转语句continue_跳转语句goto_一维数组数组_数组定义_数组名---C++语言工作笔记019
  3. ES6新特性_变量的解构赋值---JavaScript_ECMAScript_ES6-ES11新特性工作笔记006
  4. 项目管理001---认识敏捷开发
  5. 项目业务工作笔记001---发改委职责
  6. JAVA零碎要点014---java+selenium环境搭建_浏览器自动化测试框架
  7. SOA学习笔记001---SOA 服务架构之简介及理解
  8. APPCAN学习笔记006_创建第一个APPCAN应用
  9. pytorch 训练人脸精度不达标
  10. 字符串指针的地址的传递