####1,创建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">
<!--内容区域-->
<FrameLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1" />
<android.support.v4.app.FragmentTabHost
android:id="@android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
注意:
1,FragmentTabHost的id必须指定为android默认的控件id:tabhost。
2,Tab组件在上面或者下面,就看你的内容区域是怎么定义的了。
3,内容区必须设置layout_weight=“1”,对应的tab中也要设置layout_height=“wrap_content”,不然会发生显示不全哟。内容区这样设置的目的是让它自动的布满,但是不会覆盖掉Tab的内容。
4,FragmentTabHost在Xml中这样定义就可以了,不需要再多的控件。预览的时候你会发现预览不了,不用管就好了,就算你把它提示需要的东西全部添加上了,依旧会找茬- -如下~
####2,Java中的实现
首先上一段最简单的实现方式,下面我再仔细的讲讲
public class MyTabHost extends FragmentActivity {
private FragmentTabHost tabHost;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.布局文件);
tabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
//设置更改内容区域
tabHost.setup(this, getSupportFragmentManager(), R.id.content);
//添加下方内容
tabHost.addTab(tabHost.newTabSpec("标签").setIndicator("视图(View)"), ".class(指向View的类)", null);
}
}
注意:
1,首先定义出FragmentTabHost组件就不用讲了吧~
2,调用tabHost的setup方法,源代码中提供了三个setup方法,如下
我们直接使用第三个(会了第三个其他俩个都不用讲了拉~),传入一个上下文对象,传入一个FragmentManager,传入一个更改内容的布局(就是上面id为content的FrameLayout)
*用于我们这个类是extends的FragmentActivity(android.support.v4.app.FragmentActivity;)
所以传入的FragmentManager是getSupportFragmentManager()。
3,下方tabs的添加,调用addTab方法 你有几个tab就add几次~然后我们具体讲一下这个传入参数的问题
#####参数一 :重点关注这个 TabHost.TabSpec tabSpec参数
这个参数就是传入的你需要tab的View,源代码中提供了三个方法:
分别是:
1.仅设置一个标题;
2.设置一个标题和一个图标;
3.自定义一个View传入(可以理解成ListView一样)
前面俩个就不说了,讲讲第3个方法:
/* 不可以使用Button组件作为点击事件切换 */
View view = getLayoutInflater().inflate(R.layout.tabs控件你想要的布局自定义, null);
/* 得到了view 然后就跟平常的布局一样,设置吧~ 最后把view做参数一传入 */
#####参数二 :Class
这里传入的是一个extends了Fragment的类。.class
类当中就是内容区域具体显示的内容,与一些操作了~
要注意的是:俩个类继承的Frament的包要是相同的*
比如我这里继承的是android.support.v4.app.FragmentActivity;
那么内容中的类也必须是继承的android.support.v4.app.FragmentActivity;
#####参数三 :传个null 就好 = =
####3,设置切换事件
TabHost中的内容切换不用管,这里涉及到的是tabs的点击事件。具体的内容切换是默认完成的,不需要再额外写什么。
需要考虑优化小狮子可以另外百度下吧初级点的优化就是切换的Fragment中左下判断,判断View是否已经加载过了。高级点的优化就是重写FragmentTabHost中的切换事件了。具体可以百度一下~~我就不逼逼了,这里主要不讲优化QAQ
tabHost.setOnTabChangedListener(new TabHost.OnTabChangeListener() {
@Override
public void onTabChanged(String tabId) {
tabId为上面设置的title值;
}
);
####4,封装好的模块~ 有需要的可以复制过去改改图片资源就能跑起来了~
public class MyTabHost extends FragmentActivity {
private FragmentTabHost tabHost;
private String title[] = {"标题一", "标题二", "标题三"}; //按钮下方标题
private List<View> viewList; //布局样式
private Class fragmentItem[] = {Fragment1.class, Fragment2.class, Fragment3.class}; //每个单独的Fragment对应的类
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_car);
//初始化tabs样式~
initView();
//初始化tabs
initTabs();
//添加监听事件
listener();
}
private void initView() {
viewList = new ArrayList<>();
for (int i = 0; i < title.length; i++) {
//获取切换按钮的布局
View view = getLayoutInflater().inflate(R.layout.tabs, null);
//我这里布局中只有一个TextView,因为使用Button添加切换事件是没有效果的,所以使用TextView添加背景实现按钮样式
TextView textView = (TextView) view.findViewById(R.id.tabs_btn);
//第一个默认选中样式
if(i == 0){
textView.setTextColor(Color.WHITE); //文字白色,未选中黑色
textView.setBackgroundResource(R.drawable.tabs_visitor_on); //按下的背景图
}
//设置标题
textView.setText(title[i]);
//添加到List中,下面循环添加~
viewList.add(view);
}
}
private void initTabs() {
tabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
//设置更改内容区域
tabHost.setup(this, getSupportFragmentManager(), R.id.content);
//遍历添加
for (int i = 0; i < fragmentItem.length; i++) {
//这样写新手容易看懵逼,我把它拆分开来
//tabHost.addTab(tabHost.newTabSpec(title[i]).setIndicator(viewList.get(i)), fragmentItem[i], null);
//拆分写
//创建TabSpec,给定一个title,切换事件中就是根据title来判断的
TabHost.TabSpec tabSpec = tabHost.newTabSpec(title[i]);
//设置视图,选择使用源代码中的第三个方法,传入自定义的样式~
tabSpec.setIndicator(viewList.get(i));
//添加到tabHost中: tabSpec,对应的类,null
tabHost.addTab(tabSpec, fragmentItem[i], null);
}
}
//监听选项卡
private void listener() {
tabHost.setOnTabChangedListener(new TabHost.OnTabChangeListener() {
@Override
public void onTabChanged(String tabId) {
/**方法一*/
//获取下方tab
TabWidget tab = tabHost.getTabWidget();
//遍历下方tabs数量
for (int i = 0 ; i < tab.getChildCount() ; i ++){
//获取单个tabs的View
View view = tab.getChildAt(i);
//根据View获取View中的TextView
TextView text = (TextView) view.findViewById(R.id.tabs_btn);
//当前tabHost选中的
if(tabHost.getCurrentTab() == i){
text.setTextColor(Color.WHITE);
text.setBackgroundResource(R.drawable.tabs_visitor_on);
}else{
text.setTextColor(Color.BLACK);
text.setBackgroundResource(R.drawable.tabs_visitor);
}
}
/**方法二*/
//遍历标题.切换事件中的tabId参数便是title赋的
//通过判断tabId是否equals来进行指定操作
for(int i = 0 ; i < title.length ; i ++){
View view = tabsView[i];
TextView text = (TextView) view.findViewById(R.id.tabs_btn);
if(tabId.equals(title[i])){
text.setBackgroundResource(R.drawable.tabs_visitor_on);
text.setTextColor(Color.WHITE);
}else{
text.setBackgroundResource(R.drawable.tabs_visitor);
text.setTextColor(Color.BLACK);
}
}
}
});
}
}