简介

Container for a tabbed window view. This object holds two children: a set of tab labels that the

user clicks to select a specific tab, and a FrameLayout object that displays the contents of that

page. The individual elements are typically controlled using this container object, rather than

setting values on the child elements themselves.

TabHost ,标签视图的容器。容器包含两个孩子节点,一个用来存放一系列的标签,点击来选择对应的窗口;一个是FrameLayout用来存放页面具体内容。这些独立的元素通常用TabHost来控制,而不是在视图内部通过设置值来实现


类结构

方法 意义
addTab 添加一个tab
clearAllTabs 移除所有的tab
dispatchKeyEvent 下发keyevent
dispatchWindowFocusChanged 下发windowsfocusChanged事件
newTabSpec 创建一个新的TabSpec,关联到具体内容
onTouchModeChanged NA
setup() 不和TabActivity关联,通过findViewById获取的TabHost需要调用setup(),如果是在TabActivity中通过getTabHost()的方式获取的不需要调用这个方法
setup(LocalActivityManager activityGroup) setContent中传入intent的时候才关注下这个方法
getCurrentTab()/setCurrentTab() 获取/设置当前需要显示的tab,通过index
setCurrentTabByTag/getCurrentTabTag 通过tag设置当前需要显示的Tab,tag就是创建TabSpec的时候传入的字符串
getCurrentTabView 设置/获取当前在TabWidget中显示的View,也就是作为标签的View而非内容
getCurrentView 获取当前显示的内容
setOnTabChangedListener 设置标签页切换事件监听
getTabContentView 获取内容页面的容器FrameLayout
getTabWidget 获取TabWidget

基本使用

1. 布局文件(content_fragment.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"> <android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorTopBackGround"></android.support.v7.widget.Toolbar> <TabHost
android:id="@+id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent"> <LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- 设置的id必须是 "@android:id/tabcontent"-->
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="9"> <TextView
android:id="@+id/tv_one"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="This is one"
android:textColor="@color/colorAccent"
android:textSize="20sp" /> <TextView
android:id="@+id/tv_two"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="This is two"
android:textColor="@color/colorPrimary"
android:textSize="25sp" /> <TextView
android:id="@+id/tv_three"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="This is three"
android:textColor="@color/colorPrimaryDark"
android:textSize="30sp" /> <TextView
android:id="@+id/tv_four"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="This is Four"
android:textColor="@color/colorBlack"
android:textSize="35sp" />
</FrameLayout> <!-- 设置的id必须是android:id="@android:id/tabs" -->
<TabWidget
android:id="@android:id/tabs"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="@color/colorWhite"
android:padding="5dp"
android:showDividers="none"></TabWidget>
</LinearLayout>
</TabHost>
</LinearLayout>

2. 自定义底部标签布局(myindicator.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="@+id/iv_indicator"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="5"></ImageView> <TextView
android:id="@+id/tv_indicator"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2.5"
android:gravity="center"
android:textSize="5pt" />
</LinearLayout>

底部一个图标下面一段文字

3. 代码使用(MainActivity.java),不使用TabActivity

public class MainActivity extends AppCompatActivity {
float initx = 0.0f, currentx = 0.0f;
TabHost tabHost = null;
Toolbar toolbar = null; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_fragment);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);//设置ActionBar
toolbar.setTitleTextColor(getResources().getColor(R.color.colorWhite));//设置背景色
tabHost = (TabHost) findViewById(R.id.tabhost);
tabHost.setup();//初始化TabHost
/*添加tab*/
for (int i = 0; i < 4; i++) {
View view = LayoutInflater.from(this).inflate(R.layout.myindicator, null, false);
TextView textView = (TextView) view.findViewById(R.id.tv_indicator);
ImageView imageView = (ImageView) view.findViewById(R.id.iv_indicator); switch (i) {
case 0:
textView.setText("微信");
imageView.setImageResource(R.drawable.weixin);
tabHost.addTab(tabHost.newTabSpec("1").setIndicator(view).setContent(R.id.tv_one));
break;
case 1:
textView.setText("通讯录");
imageView.setImageResource(R.drawable.contact);
tabHost.addTab(tabHost.newTabSpec("2").setIndicator(view).setContent(R.id.tv_two));
break;
case 2:
textView.setText("发现");
imageView.setImageResource(R.drawable.find);
tabHost.addTab(tabHost.newTabSpec("3").setIndicator(view).setContent(R.id.tv_three));
break;
case 3:
textView.setText("我");
imageView.setImageResource(R.drawable.profile);
tabHost.addTab(tabHost.newTabSpec("4").setIndicator(view).setContent(R.id.tv_four));
break;
} }
/*设置标签切换监听器*/
tabHost.setOnTabChangedListener(new TabHost.OnTabChangeListener() {
@Override
public void onTabChanged(String tabId) {
for (int i = 0; i < 4; i++) {//颜色全部重置
((TextView) tabHost.getTabWidget().getChildTabViewAt(i).findViewById(R.id.tv_indicator)).setTextColor(getResources().getColor(R.color.colorBlack));
}
if (tabHost.getCurrentTabTag() == tabId) {
((TextView) tabHost.getCurrentTabView().findViewById(R.id.tv_indicator)).setTextColor(getResources().getColor(R.color.colorSelected));
}//选中的那个Tab文字颜色修改
}
});
((TextView) tabHost.getCurrentTabView().findViewById(R.id.tv_indicator)).setTextColor(getResources().getColor(R.color.colorSelected));//第一次进入的时候讲选中的Tab修改文字颜色 } @Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
initx = event.getX();
break;
case MotionEvent.ACTION_MOVE:
currentx = event.getX();
break;
case MotionEvent.ACTION_UP:
/*左右滑动事件处理*/
if ((currentx - initx) > 25) {
if (tabHost.getCurrentTab() != 0) { tabHost.setCurrentTab(tabHost.getCurrentTab() - 1);
}
} else if ((currentx - initx) < -25) {
if (tabHost.getCurrentTab() != tabHost.getTabContentView().getChildCount()) {
tabHost.setCurrentTab(tabHost.getCurrentTab() + 1);
}
}
break; } return true;
} /*菜单创建*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.toolbar, menu);
return true;
}
}

4. 代码使用(MainActivity.java),继承TabActivity

TabActivity已经被废弃很久了,但是还是可以使用,在布局中将TabHost的id改成android:id=”@android:id/tabhost”,然后在继承了TabActivity的MainActivity.java中使用

tabHost = getTabHost();

然后基本使用方法就和上面一样了


实际效果


写在最后

TabHost在TabActivity中的使用现在开发过程中使用的不多,推荐使用ViewPager和Fragment的方式

<Android 基础(三十三)> TabHost ~ 仿微信底部菜单的更多相关文章

  1. Android自己定义TabActivity(实现仿新浪微博底部菜单更新UI)

    现在Android上非常多应用都採用底部菜单控制更新的UI这样的框架,比如新浪微博 点击底部菜单的选项能够更新界面.底部菜单能够使用TabHost来实现,只是用过TabHost的人都知道自己定义Tab ...

  2. [Android] Android 使用 FragmentTabHost + Fragment 实现 微信 底部菜单

    Android 使用 FragmentTabHost + Fragment 实现 微信 底部菜单 利用FragmentTabHost实现底部菜单,在该底部菜单中,包括了4个TabSpec,每个TabS ...

  3. Android高仿qq及微信底部菜单的几种实现方式

    最近项目没那么忙,想着开发app的话,有很多都是重复,既然是重复的,那就没有必要每次都去写,所以就想着写一个app通用的基本框架,这里说的框架不是什么MVC,MVP,MVVM这种,而是app开发的通用 ...

  4. 仿微信底部自定义菜单 移动web

    最近在做微信开发,要实现微信公众号改版—-改成微官网形式,即移动web页面中实现公众号的主页面,包括了公众号的菜单在底部显示 本文针对仿公众号底部菜单这个功能实现进行总结.实现采用html和css.J ...

  5. Android开发之使用GridView+仿微信图片上传功能(附源代码)

    前言:如果转载文章请声明转载自:https://i.cnblogs.com/EditPosts.aspx?postid=7419021  .另外针对有些网站转载本人的文章结果源码链接不对的问题,本人在 ...

  6. html css 仿微信底部自己定义菜单

    近期几个月一直从事微信开发,从刚開始的懵懂渐渐成长了一点. 今天认为微信底部自己定义菜单,假设能在html的页面上也能显示就好了. 记得曾经看过某个网页有类似效果.查找了该网页的css.  ok如今h ...

  7. Android控件-ViewPager(仿微信引导界面)

    什么是ViewPager? ViewPager是安卓3.0之后提供的新特性,继承自ViewGroup,专门用以实现左右滑动切换View的效果. 如果想向下兼容就必须要android-support-v ...

  8. Android中软键盘弹出时底部菜单上移问题

    当在Android的layout设计里面如果输入框过多,则在输入弹出软键盘的时候,下面的输入框会有一部分被软件盘挡住,从而不能获取焦点输入. 解决办法: 方法一:在你的activity中的oncrea ...

  9. Android仿微信底部选项卡

    第一步 添加依赖 dependencies { compile 'com.yinglan.alphatabs:library:1.0.5' } 第二步 布局使用 <?xml version=&q ...

随机推荐

  1. c++中double类型控制小数位数

    有时,我们需要输出确定小数位数的double,可以先引入如下头文件: #include <iomanip> 然后通过下列方式输出: double zzz = 8.66666; cout & ...

  2. 转:TCP为什么要3次握手和4次挥手时等待2MSL、 TCP如何保证消息顺序以及可靠性到达

    关于tcp三次握手.四次挥手可以看这里:TCP与UDP的差别以及TCP三次握手.四次挥手 1.TCP为甚要3次握手? 在谢希仁著<计算机网络>第四版中讲“三次握手”的目的是“为了防止已失效 ...

  3. Future接口和Callable接口以及FeatureTask详解

    类继承关系 Callable接口 @FunctionalInterface public interface Callable<V> { V call() throws Exception ...

  4. Mysql大数据表优化处理

    原文链接: https://segmentfault.com/a/1190000006158186 当MySQL单表记录数过大时,增删改查性能都会急剧下降,可以参考以下步骤来优化: 单表优化 除非单表 ...

  5. CCF 201509-3 模版生成系统

    试题编号: 201509-3 试题名称: 模板生成系统 时间限制: 1.0s 内存限制: 256.0MB 问题描述 成成最近在搭建一个网站,其中一些页面的部分内容来自数据库中不同的数据记录,但是页面的 ...

  6. 前端组件化Polymer入门教程(6)——监听属性值变化

    监听属性值变化 如果需要监听属性值变化可以通过给observer赋值一个回调函数. <say-Hello></say-Hello> <dom-module id=&quo ...

  7. Spring代理

    概述 代理(Proxy)是一种设计模式, 提供了对目标对象另外的访问方式:即通过代理访问目标对象. 这样好处: 可以在目标对象实现的基础上,增强额外的功能操作.(扩展目标对象的功能). 举例:假设某用 ...

  8. mysql添加用户、修改权限,修改登录权限ip

    1.添加用户 1.1 登录MYSQL: @>mysql -u root -p @>密码 1.2 创建用户: 格式:grant select on 数据库.* to 用户名@登录主机 ide ...

  9. notepad++ jstool 插件安装

    notepad++ 格式化显示 网上下载 jstool 插件 放入Notepad++\安装目录的plugins位置下,重启即可使用 插件-->JSTool

  10. HTTPS加密越来越流行,为何要加密?

    继谷歌之后,国内最大的搜索引擎百度在2015年5月实现了全站HTTPS加密.搜狗搜索.360搜索.bing搜索.淘宝.天猫.知乎等也都实现了全站HTTPS加密,互联网即将迎来全网HTTPS加密时代. ...