一、TabHost简介
Container for a tabbed window view. Thisobject holds two children: a set of tab labels that the
user clicks toselect a specific tab, and a FrameLayout object that displays the contents ofthat
page. Theindividual elements are typically controlled using this container object,rather than
setting values onthe child elements themselves.
TabHost ,标签视图的容器。容器包含两个孩子节点,一个用来存放一系列的标签,点击来选择对应的窗口;一个是FrameLayout用来存放页面具体内容。这些独立的元素通常用TabHost来控制,而不是在视图内部通过设置值来实现。
二、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 |
三、TabHost使用步骤
1.主页UI布局
注意:在自定义自己的TabHost时,TabWiget和FrameLayout不可以自定义id,
TabHost的id定义为:android:id="@+id/tabhost"
FrameLayout的id定义为android:id="@android:id/tabcontent"
需在setup里面进行实例化,因此需要早addTab添加内容之前调用setup方法。
2.初始化UI
tabHost = (TabHost) findViewById(R.id.tabhost);
tabHost.setup();//初始化TabHost
3.初始化数据
/*添加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.mipmap.ic_launcher);
tabHost.addTab(tabHost.newTabSpec("1").setIndicator(view).setContent(R.id.tv_one));
break;
case 1:
textView.setText("通讯录");
imageView.setImageResource(R.mipmap.ic_launcher);
tabHost.addTab(tabHost.newTabSpec("2").setIndicator(view).setContent(R.id.tv_two));
break;
case 2:
textView.setText("发现");
imageView.setImageResource(R.mipmap.ic_launcher);
tabHost.addTab(tabHost.newTabSpec("3").setIndicator(view).setContent(R.id.tv_three));
break;
case 3:
textView.setText("我的");
imageView.setImageResource(R.mipmap.ic_launcher);
tabHost.addTab(tabHost.newTabSpec("4").setIndicator(view).setContent(R.id.tv_four));
break;
}
}
4.设置监听器
/*设置标签切换监听器*/
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.colorAccent));
}
if (tabHost.getCurrentTabTag() == tabId) {
((TextView) tabHost.getCurrentTabView().findViewById(R.id.tv_indicator))
.setTextColor(getResources().getColor(R.color.colorPrimary));
}//选中的那个Tab文字颜色修改
}
});
((TextView) tabHost.getCurrentTabView().findViewById(R.id.tv_indicator))
.setTextColor(getResources().getColor(R.color.colorPrimary));//第一次进入的时候讲选中的Tab修改文字颜色
5.滑动事件
@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;
}
6.另解:继承TabActivity
TabActivity已经被废弃很久了,但是还是可以使用,在布局中将TabHost的id改成android:id=”@android:id/tabhost”,然后在继承了TabActivity的MainActivity.java中使用 tabHost = getTabHost(); 然后基本使用方法就和上面一样了。
7.注意:
使用TabHost的时候,当你页面内有输入框的时候你会发现输入法会把底部tabWeight顶起来。我们可以在注册activity的时候对输入法做一些限制。
·“stateUnspecified” 软键盘的状态(是否它是隐藏或可见)没有被指定。系统将选择一个合适的状态或依赖于主题的设置。这个是为了软件盘行为默认的设置。
·“stateUnchanged” 软键盘被保持无论它上次是什么状态,是否可见或隐藏,当主窗口出现在前面时。
·“stateHidden” 当用户选择该Activity时,软键盘被隐藏——也就是,当用户确定导航到该Activity时,而不是返回到它由于离开另一个Activity。
·“stateAlwaysHidden” 软键盘总是被隐藏的,当该Activity主窗口获取焦点时。
·“stateVisible” 软键盘是可见的,当那个是正常合适的时(当用户导航到Activity主窗口时)。
·“stateAlwaysVisible” 当用户选择这个Activity时,软键盘是可见的——也就是,也就是,当用户确定导航到该Activity时,而不是返回到它由于离开另一个Activity。
·“adjustUnspecified” 它不被指定是否该Activity主窗口调整大小以便留出软键盘的空间,或是否窗口上的内容得到屏幕上当前的焦点是可见的。系统将自动选择这些模式中一种主要依赖于是否窗口的内容有任何布局视图能够滚动他们的内容。如果有这样的一个视图,这个窗口将调整大小,这样的假设可以使滚动窗口的内容在一个较小的区域中可见的。这个是主窗口默认的行为设置。
·“adjustResize” 该Activity主窗口总是被调整屏幕的大小以便留出软键盘的空间。
·“adjustPan” 该Activity主窗口并不调整屏幕的大小以便留出软键盘的空间。相反,当前窗口的内容将自动移动以便当前焦点从不被键盘覆盖和用户能总是看到输入内容的部分。这个通常是不期望比调整大小,因为用户可能关闭软键盘以便获得与被覆盖内容的交互操作。
四、效果图
五、续言
Fragment是Android 3.0 引入的新API,他使开发的效率更加高效,在前面的例子我们也看到Fragment不止能解决Android Pad屏幕比较大,空间不能充分利用的问题,即使只是在手机上,也有很多的场景可以运用到Fragment,我们可能会注意到很多手机应用都会有一个非常类似的功能——即屏幕的下方显示一行Tab标签选项,点击不同的标签就可以切换到不同的界面,例如微信、QQ、支付宝等。大家可能马上就想到了TabHost,但是殊不知,TabHost并非是那么的简单,它的可扩展性非常的差,不能随意地定制Tab项显示的内容,而且运行还要依赖于ActivityGroup。ActivityGroup原本主要是用于为每一个TabHost的子项管理一个单独的Activity,但目前已经被废弃了。为什么呢?当然就是因为Fragment的出现了!查看Android官方文档中ActivityGroup的描述,如下所示:
可以看到,在API 13的时候Android就已经将ActivityGroup废弃掉了,并且官方推荐的替代方式就是使用Fragment,因为它使用起来更加的灵活。
六、源码下载
地址:http://download.csdn.net/download/u012721519/10243603
Good luck!
Write by Jimmy.li