简介

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. java.io.IOException: Stream closed解决办法

    1.出现这个bug的大体逻辑代码如下: private static void findMovieId() throws Exception { File resultFile = new File( ...

  2. android studio 查看包有没有重复引用

    在windows下studio内的命令行里面     gradlew :app:dependencies 苹果系统  ./gradlew :app:dependencies

  3. 装饰者模式——Java设计模式

    装饰模式 1.概念 动态地为对象附加上额外的职责 其目的是包装一个对象,从而可以在运行时动态添加新的职责.每个装饰器都可以包装另一个装饰器,这样理论上来说可以对目标对象进行无限次的装饰. 2.装饰器类 ...

  4. Docker快速入门(一)

    Docker是Go语言开发实现的容器.2013年发布至今,备受推崇.相关文档.学习资料十分详尽.近期公司docker项目要推进,得重新学习一下.博客以笔记. 1 容器诞生背景及优势 (1)软件开发和运 ...

  5. 扩容swap空间

    添加swap空间 适用场景: 安装系统时未分区swap,完成安装后又需使用swap的 swap空间不足,需要扩容 解决方法: 一.添加磁盘作为swap使用 添加磁盘 [root@test ~]# fd ...

  6. Java中数据类型转换大全(个人总结)

    一.字符串转换为其他类型 1.将字符串转化为int型 (1)方法一 int i = Integer.parseInt(String str); (2)方法二 int i = Integer.value ...

  7. springMVC和json整合配置方法

    一.配置方法一 1.导入第三方的jackson包,jackson-mapper-asl-1.9.13.jar和jackson-core-asl-1.9.13.jar 百度云链接:https://pan ...

  8. C# Quartz的配置

    1. 介绍 Quartz为后台工作者提供了得便利,我们下面介绍一下它的配置.本文配置主要针对服务程序的配置. 但是在做下面配置之前,要安装包 Install-Package Quartz 2. Qua ...

  9. C# Azure-让http自动跳转到https链接

    在项目的web.config下面加上下面的配置: <rewrite> <rules> <clear /> <rule name="Redirect ...

  10. ASP.NET开发,且编且改,分清职责

    本篇Insus.NET使用一个实例,分享在ASP.NET开发时,一个功能一个方法(函数),且编且改,一步一个脚印把实例完成.在方法多变多形式的情况之下,怎样把写出来程序简单明了. 下面是一个Excel ...