结合源码讲解Tabost
本文结合源代码和实例来说明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相关推荐
- C++简介源码讲解精辟版,C++入门级C++学习,C++与C的区别值得知晓
C++简介源码讲解精辟版,C++入门级C++学习,C++与C的区别值得知晓 C语言和C++基础区别 C++标准输入和输出 命名空 1.命名空间的定义 : namespace 标识符{ } 例:name ...
- ORB特征点提取与均匀化——ORBSLAM2源码讲解(一)
文章目录 前言 一.基础知识 二.ORB特征均匀化策略对性能的影响 三.ORB特征金字塔 四.ORB提取扩展图像 五.ORB特征均匀化 总结 前言 本博客结合哔哩大学视频ORBSLAM2[ORBSLA ...
- 顾客信息表mysql_Qt5.5.0使用mysql编撰小软件源码讲解-顾客信息登记表_mysql
Qt5.5.0使用mysql编写小软件源码讲解---顾客信息登记表 Qt5.5.0使用mysql编写小软件源码讲解---顾客信息登记表 一个个人觉得比较简单小巧的软件. 下面就如何编写如何发布打包来介 ...
- Oriented Fast神奇高效的代码实现方式——ORBSLAM2源码讲解(二)
文章目录 前言 一.基础知识 二.灰度质心法原理 三.UMAX 四.IC_Angle如何做加速运算 总结 前言 本博客结合哔哩大学视频ORBSLAM2[ORBSLAM2源码讲解专题一]ORB特征点提取 ...
- 27.串口通信实验源码讲解
串口通信实验源码讲解 笔记基于正点原子官方视频 视频连接https://www.bilibili.com/video/BV1Wx411d7wT?p=71&spm_id_from=333.100 ...
- 双目相机标定OpenCV源码讲解
双目相机标定OpenCV源码讲解 背景介绍 所述内容 参考资料 摄像机标定部分代码 代码思路 代码中的其他函数 找角点&求内参 求外参 求矫正映射矩阵 后记 背景介绍 暑假接近两个月的时间做了 ...
- android飞信短信箱程序源码讲解
android飞信短信箱程序源码讲解! 一.程序演示 图1.进入程序后的第1页面,头部的新消息提示在任意页面都会弹出. 图2.未读消息数量提示,任意页面. 图3.点击新建短信,(或者会话中的转发选项) ...
- 讲解java源码_Java学习之Java源码讲解
关于Java中源码的学习,是不少同学头疼的知识点.本文整理了JAVA源码学习的八大要点,分别是基础知识.面向对象.异常处理.集合.综合类核心代码.JAVA8新特性.Input/Output和Java小 ...
- OpenCV SIFT源码讲解——代码逻辑宏观窥探
OpenCV SIFT源码讲解--代码逻辑宏观窥探 一.暴露在外的接口:SIFT 二.隐藏在SIFT背后的本质:SIFT_Impl 三.使用sift算法全流程 一.暴露在外的接口:SIFT 一般来说, ...
最新文章
- 802.1x 客户端获取ip过程 很详细
- 黑马程序员_java异常处理机制
- 条件概率 and 条件概率的链式法则 and 期望、方差和协方差
- spring mvc学习(60):ssm项目整合
- 数据分析案例:亚洲国家人口数据计算
- poj1064 二分搜索 挑战程序设计竞赛
- Linux 文件内容替换命令
- 理解伪元素:before和:after
- 数据库系统工程师考点
- hadoop 空间配置
- 如何在网上下载自己需要的资源
- 如何获取div中的value值
- 正则表达式与文件格式处理-Linux(笔记)
- markdown: 欢迎使用马克飞象
- 小丁带你走进git世界一-git简单配置
- P2394 yyy loves Chemistry I
- 华为运营商级路由器配置示例 | 配置OptionB方式跨域BGP VPLS示例(ASBR兼做PE)
- 降低PNG图片存储大小方法、图片压缩方法
- 查词app android教程,英语查单词app哪个好_查单词app推荐_专门查单词的app
- 7-114 用if-else语句编程百分制成绩转换为五分制成绩
热门文章
- C++_类和对象_C++运算符重载_左移运算符重载_链式编程_实现直接打印对象---C++语言工作笔记056
- C++_跳转语句continue_跳转语句goto_一维数组数组_数组定义_数组名---C++语言工作笔记019
- ES6新特性_变量的解构赋值---JavaScript_ECMAScript_ES6-ES11新特性工作笔记006
- 项目管理001---认识敏捷开发
- 项目业务工作笔记001---发改委职责
- JAVA零碎要点014---java+selenium环境搭建_浏览器自动化测试框架
- SOA学习笔记001---SOA 服务架构之简介及理解
- APPCAN学习笔记006_创建第一个APPCAN应用
- pytorch 训练人脸精度不达标
- 字符串指针的地址的传递