使用FragmentTabHost+TabLayout+ViewPager实现双层嵌套Tab
来源:互联网 发布:云顶娱乐软件下载 编辑:程序博客网 时间:2024/05/16 23:51
大多数应用程序都会在底部使用3~5个Tab对应用程序的主要功能进行划分,对于一些信息量非常大的应用程序,还需要在每个Tab下继续划分子Tab对信息进行分类显示.
本文实现采用FragmentTabHost+TabLayout+ViewPager实现双层嵌套Tab,实现原理如下:
第一层Tab:FragmentTabHost + Fragment;
第二层Tab:在第一层的Fragment中使用TabLayout和ViewPager实现.
第一层Tab实现:
1.布局文件activity_main.xml如下:
1 <?xml version="1.0" encoding="utf-8"?> 2 <android.support.v4.app.FragmentTabHost android:id="@android:id/tabhost" 3 xmlns:android="http://schemas.android.com/apk/res/android" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent"> 6 7 <LinearLayout 8 android:layout_width="match_parent" 9 android:layout_height="match_parent"10 android:orientation="vertical">11 <FrameLayout12 android:id="@android:id/tabcontent"13 android:layout_width="match_parent"14 android:layout_height="0dp"15 android:layout_weight="1"/>16 17 <TabWidget18 android:id="@android:id/tabs"19 android:layout_width="match_parent"20 android:layout_height="?attr/actionBarSize"21 android:layout_gravity="bottom"/>22 </LinearLayout>23 24 </android.support.v4.app.FragmentTabHost>
说明:其中FrameLayout用于显示内容,TabWidget用于显示标签。
2.底部Tab布局:view_tab_indicator.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center"> <ImageView android:id="@+id/tab_iv_image" android:layout_width="26dp" android:layout_height="26dp" android:contentDescription="@null"/> <TextView android:id="@+id/tab_tv_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="1dp" android:textColor="#ff847d7b" android:textSize="12sp"/></LinearLayout>
底部Tab由一张图片和tab名称组成。
3.在mainActivity.java中定义一个内部类TabItem,用于表示底部tab:
1 class TabItem { 2 //正常情况下显示的图片 3 private int imageNormal; 4 //选中情况下显示的图片 5 private int imagePress; 6 //tab的名字 7 private int title; 8 private String titleString; 9 10 //tab对应的fragment11 public Class<? extends Fragment> fragmentClass;12 13 public View view;14 public ImageView imageView;15 public TextView textView;16 17 public TabItem(int imageNormal, int imagePress, int title,Class<? extends Fragment> fragmentClass) {18 this.imageNormal = imageNormal;19 this.imagePress = imagePress;20 this.title = title;21 this.fragmentClass =fragmentClass;22 }23 24 public Class<? extends Fragment> getFragmentClass() {25 return fragmentClass;26 }27 public int getImageNormal() {28 return imageNormal;29 }30 31 public int getImagePress() {32 return imagePress;33 }34 35 public int getTitle() {36 return title;37 }38 39 public String getTitleString() {40 if (title == 0) {41 return "";42 }43 if(TextUtils.isEmpty(titleString)) {44 titleString = getString(title);45 }46 return titleString;47 }48 49 public View getView() {50 if(this.view == null) {51 this.view = getLayoutInflater().inflate(R.layout.view_tab_indicator, null);52 this.imageView = (ImageView) this.view.findViewById(R.id.tab_iv_image);53 this.textView = (TextView) this.view.findViewById(R.id.tab_tv_text);54 if(this.title == 0) {55 this.textView.setVisibility(View.GONE);56 } else {57 this.textView.setVisibility(View.VISIBLE);58 this.textView.setText(getTitleString());59 }60 this.imageView.setImageResource(imageNormal);61 }62 return this.view;63 }64 65 //切换tab的方法66 public void setChecked(boolean isChecked) {67 if(imageView != null) {68 if(isChecked) {69 imageView.setImageResource(imagePress);70 }else {71 imageView.setImageResource(imageNormal);72 }73 }74 if(textView != null && title != 0) {75 if(isChecked) {76 textView.setTextColor(getResources().getColor(R.color.main_botton_text_select));77 } else {78 textView.setTextColor(getResources().getColor(R.color.main_bottom_text_normal));79 }80 }81 }82 }
4.初始化Tab数据:
1 //初始化Tab数据2 private void initTabData() {3 mTableItemList = new ArrayList<>();4 //添加tab5 mTableItemList.add(new TabItem(R.drawable.main_bottom_home_normal,R.drawable.main_bottom_home_press,R.string.main_home_text, TestFragment1.class));6 mTableItemList.add(new TabItem(R.drawable.main_bottom_attention_normal,R.drawable.main_bottom_attention_press,R.string.main_attention_text, TestFragment2.class));7 mTableItemList.add(new TabItem(R.drawable.main_bottom_mine_normal,R.drawable.main_bottom_mine_press,R.string.main_mine_text, TestFragment3.class));8 9 }
5.初始化选项卡视图:
1 //初始化主页选项卡视图 2 private void initTabHost() { 3 //实例化FragmentTabHost对象 4 FragmentTabHost fragmentTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost); 5 fragmentTabHost.setup(this,getSupportFragmentManager(),android.R.id.tabcontent); 6 7 //去掉分割线 8 fragmentTabHost.getTabWidget().setDividerDrawable(null); 9 10 for (int i = 0; i<mTableItemList.size(); i++) {11 TabItem tabItem = mTableItemList.get(i);12 //实例化一个TabSpec,设置tab的名称和视图13 TabHost.TabSpec tabSpec = fragmentTabHost.newTabSpec(tabItem.getTitleString()).setIndicator(tabItem.getView());14 fragmentTabHost.addTab(tabSpec,tabItem.getFragmentClass(),null);15 16 //给Tab按钮设置背景17 fragmentTabHost.getTabWidget().getChildAt(i).setBackgroundColor(getResources().getColor(R.color.main_bottom_bg));18 19 //默认选中第一个tab20 if(i == 0) {21 tabItem.setChecked(true);22 }23 }24 25 fragmentTabHost.setOnTabChangedListener(new TabHost.OnTabChangeListener() {26 @Override27 public void onTabChanged(String tabId) {28 //重置Tab样式29 for (int i = 0; i< mTableItemList.size(); i++) {30 TabItem tabitem = mTableItemList.get(i);31 if (tabId.equals(tabitem.getTitleString())) {32 tabitem.setChecked(true);33 }else {34 tabitem.setChecked(false);35 }36 }37 }38 });39 }
6.在oncreate()中调用以上两个方法:
1 @Override2 protected void onCreate(Bundle savedInstanceState) {3 super.onCreate(savedInstanceState);4 setContentView(R.layout.activity_main);5 initTabData();6 initTabHost();7 }
至此,第一层tab实现完成,效果如下图所示:
第二层Tab实现:
第二层的tab基于第一层中的Fragment实现,本文使用了TabLayout和ViewPager。
注意:在使用TabLayout之前需要添加依赖包,例如在build.gradle中添加compile 'com.android.support:design:23.3.0'。
1.第二层tab的布局文件:
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:app="http://schemas.android.com/apk/res-auto" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:clickable="true" 6 android:orientation="vertical"> 7 8 9 <android.support.design.widget.TabLayout10 android:id="@+id/tab_essence"11 android:layout_width="match_parent"12 android:layout_height="40dp"13 android:background="@color/essence_tab_bg"14 app:tabMode="scrollable"15 app:tabSelectedTextColor="@color/essence_tab_text_color_press"16 app:tabTextColor="@color/essence_tab_text_color_normal"17 app:tabIndicatorColor="@color/essence_tab_text_color_press"/>18 19 <android.support.v4.view.ViewPager20 android:id="@+id/vp_essence"21 android:layout_width="match_parent"22 android:layout_height="match_parent"23 app:layout_behavior="@string/appbar_scrolling_view_behavior" />24 25 </LinearLayout>
其中TabLayout用于显示子tab,VierPager用于显示子tab对应的内容。
2.在strings.xml中配置标签数据:
1 <array name="home_video_tab">2 <item>全部@dream@0</item>3 <item>视频@dream@1</item>4 <item>声音@dream@2</item>5 <item>图片@dream@3</item>6 <item>段子@dream@4</item>7 <item>广告@dream@5</item>8 <item>剧情@dream@6</item>9 </array>
3.定义显示在ViewPager中的Fragment:
1 public class ContentFragment extends Fragment { 2 3 private View viewContent; 4 private int mType = 0; 5 private String mTitle; 6 7 8 public void setType(int mType) { 9 this.mType = mType;10 }11 12 public void setTitle(String mTitle) {13 this.mTitle = mTitle;14 }15 16 17 @Nullable18 @Override19 public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {20 //布局文件中只有一个居中的TextView21 viewContent = inflater.inflate(R.layout.fragment_content,container,false);22 TextView textView = (TextView) viewContent.findViewById(R.id.tv_content);23 textView.setText(this.mTitle);24 25 return viewContent;26 }27 28 }
4.定义ViewPager的adapter:
1 //继承FragmentStatePagerAdapter 2 public class TestFragmentAdapter extends FragmentStatePagerAdapter { 3 4 public static final String TAB_TAG = "@dream@"; 5 6 private List<String> mTitles; 7 8 public TestFragmentAdapter(FragmentManager fm, List<String> titles) { 9 super(fm);10 mTitles = titles;11 }12 13 @Override14 public android.support.v4.app.Fragment getItem(int position) {15 //初始化Fragment数据16 ContentFragment fragment = new ContentFragment();17 String[] title = mTitles.get(position).split(TAB_TAG);18 fragment.setType(Integer.parseInt(title[1]));19 fragment.setTitle(title[0]);20 return fragment;21 }22 23 @Override24 public int getCount() {25 return mTitles.size();26 }27 28 @Override29 public CharSequence getPageTitle(int position) {30 return mTitles.get(position).split(TAB_TAG)[0];31 }32 }
5.Fragment具体实现:
1 public class TestFragment1 extends android.support.v4.app.Fragment{ 2 3 private View viewContent; 4 private TabLayout tab_essence; 5 private ViewPager vp_essence; 6 7 @Nullable 8 @Override 9 public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {10 viewContent = inflater.inflate(R.layout.fragment_test_1,container,false);11 initConentView(viewContent);12 initData();13 14 return viewContent;15 }16 17 public void initConentView(View viewContent) {18 this.tab_essence = (TabLayout) viewContent.findViewById(R.id.tab_essence);19 this.vp_essence = (ViewPager) viewContent.findViewById(R.id.vp_essence);20 }21 22 public void initData() {23 //获取标签数据24 String[] titles = getResources().getStringArray(R.array.home_video_tab);25 26 //创建一个viewpager的adapter27 TestFragmentAdapter adapter = new TestFragmentAdapter(getFragmentManager(), Arrays.asList(titles));28 this.vp_essence.setAdapter(adapter);29 30 //将TabLayout和ViewPager关联起来31 this.tab_essence.setupWithViewPager(this.vp_essence);32 }33 }
至此,第二层tab实现完成,效果如下:
总结:
1.本文实现的双层嵌套Tab使用到了FragmentTabHost,Fragment,ViewPager和TabLayout.
2.内外层的实现是解耦的,外层实现使用的是FragmentTabHost+Fragment,内层的实现是对外层Fragment的扩展,实现方式是使用TabLayout+VierPager。
原文地址:http://www.cnblogs.com/happyhacking/p/5573246.html
- 使用FragmentTabHost+TabLayout+ViewPager实现双层嵌套Tab
- 使用FragmentTabHost+TabLayout+ViewPager实现双层嵌套Tab
- 使用FragmentTabHost+TabLayout+ViewPager实现双层嵌套Tab
- 使用FragmentTabHost+TabLayout+ViewPager实现双层嵌套Tab
- 使用FragmentTabHost实现仿QQ的切换,并在里面嵌套TabLayout+ViewPager的滑动切换
- FragmentTabHost+Fragment+ViewPager实现内外层嵌套Tab
- FragmentTabHost+Fragment+ViewPager实现内外层嵌套Tab
- FragmentTabHost+Fragment+ViewPager实现内外层嵌套Tab
- FragmentTabHost+ViewPager+Fragment实现底部Tab导航
- FragmentTabHost+Fragment+ViewPager实现内外层嵌套
- FragmentTabHost+Fragment+ViewPager实现内外层嵌套
- FragmentTabHost+Fragment+ViewPager实现内外层嵌套
- 使用FragmentTabHost实现Tab页
- VIewpager双层嵌套
- TabLayout+Fragment+ViewPager+FragmentStatePagerAdapter实现Tab标签
- TabLayout与ViewPager组合实现tab导航
- Android TabLayout与ViewPager实现动态Tab
- 使用TabLayout实现不规则Tab
- HTTP请求中的缓存(cache)机制
- HTML基本结构、CSS引入方式以及选择器
- 关于libcef出现关闭崩溃的情况
- CentOS安装php加速软件Zend Guard
- 155. Min Stack
- 使用FragmentTabHost+TabLayout+ViewPager实现双层嵌套Tab
- typedef与define的用法和区别
- Linux 五个最牛视频编辑软件
- qt-creator中的 运行程序的 工作目录 与 程序所在的目录
- 盒模型基础知识简述
- Java基础——成员变量、局部变量和静态变量的区别
- PyCharm2016.3使用贴士及安装和汉化
- 20161126
- Java泛型