使用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

0 0