## (一).前言:
仿36Kr客户端开发过程中,因为他们网站上面的新闻文章分类比较多,所以我这边还是打算模仿网易新闻APP的主界面新闻标签Tab以及页面滑动效果来进行实现。要实现的顶部的Tab标签的效果有很多方法例如采用开源项目ViewPagerIndicator中的TabPageIndicator就可以实现。不过我们今天不讲ViewPagerIndicator,我们来讲一下Google今年发布的TabLayout组件。在2015年的Google大会上,google发布的新的Android SupportDesign库,里面也包含了几个新的控件,那么TabLayout就是其中一个。使用该组件我们可以很轻松的实现TabPageIndicator效果,并且该为官方的,可以向下兼容很多版本而且可以更加统一Material Design效果。不过查看TabLayout的源码发现该组件也是继承自HorizontalScrollView实现。
[使用HorizontalScrollView打造仿网易tab标签效果,点击进入...](http://blog.csdn.net/developer_jiangqq/article/details/50145759)
本例子具体代码已经上传到下面的项目中,欢迎各位去star和fork一下。
FastDev4Android框架项目地址:[https://github.com/jiangqqlmj/FastDev4Android](https://github.com/jiangqqlmj/FastDev4Android)
## (二).使用方式:
2.1.我这边的项目采用Android Studio进行开发的,所以首先要引入TabLayout的依赖库,如下:
~~~
compile'com.android.support:design:23.1.1'
compile'com.android.support:appcompat-v7:23.1.1'
~~~
![](https://box.kancloud.cn/2016-01-18_569c8ec6e72fc.jpg)
## (三).效果实现:
我们现在需要仿照网易新闻(36Kr客户端)的Tab标签切换以及底部新闻页面切换的效果。Tab标签实现采用TabLayout组件,底部页面切换采用Fragment+ViewPager+FragmentStatePagerAdapter实现。
[注]:承载Fragment的Activity这边就不讲解了,具体可以看上一篇文章和本项目的代码即可。那我们直接从Fragment开始讲起。
3.1.首先我们需要给Fragment创建一个布局文件如下:
~~~
<?xmlversion="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"android:layout_width="match_parent"
android:layout_height="match_parent">
<!--顶部tab标签容器-->
<android.support.design.widget.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/tab_layout"
android:background="@color/white"
app:tabIndicatorColor="@color/color_selected"
app:tabSelectedTextColor="@color/color_selected"
app:tabTextColor="@color/color_unselected"
></android.support.design.widget.TabLayout>
<android.support.v4.view.ViewPager
android:id="@+id/info_viewpager"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
~~~
该布局主要为两个控件:第一部分为TableLayout组件该为Tab标签的容器,第二部分为ViewPager组件主要用于显示若干个Fragment进行页面切换。大家在TabLayout组件中应该已经注意到了三个自定义属性如下:
~~~
app:tabIndicatorColor="@color/white" // 下方滚动的下划线颜色
app:tabSelectedTextColor="@color/gray" // tab被选中后,文字的颜色
app:tabTextColor="@color/white" // tab默认的文字颜色
~~~
这三个自定义属性是TabLayout提供的,我们可以任意修改标题颜色以及指示器的颜色,除此之外还提供了以下一些风格设置方法:
* tabMaxWidth
* tabIndicatorColor
* tabIndicatorHeight
* tabPaddingStart
* tabPaddingEnd
* tabBackground
* tabTextAppearance
* tabSelectedTextColor
3.2.接着是是CNKFixedPagerAdapter,该为ViewPager的自定义适配器,在ViewPager中的每一项采用Fragment实现,所以传入了得Fragment的页面的集合,同时还定义了Tab显示标题的数组。
~~~
package com.chinaztt.fda.adapter;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.chinaztt.fda.application.FDApplication;
import com.chinaztt.fda.ui.R;
import java.util.List;
/**
* 当前类注释:Fragment,Viewpager的自定义适配器
* 项目名:FastDev4Android
* 包名:com.chinaztt.fda.adapter
* 作者:江清清 on 15/12/2 10:08
* 邮箱:jiangqqlmj@163.com
* QQ: 781931404
* 公司:江苏中天科技软件技术有限公司
*/
public class CNKFixedPagerAdapter extends FragmentStatePagerAdapter {
private String[] titles;
private LayoutInflater mInflater;
public void setTitles(String[] titles) {
this.titles = titles;
}
private List<Fragment> fragments;
public CNKFixedPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
return this.fragments.get(position);
}
@Override
public int getCount() {
return this.fragments.size();
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment=null;
try {
fragment=(Fragment)super.instantiateItem(container,position);
}catch (Exception e){
}
return fragment;
}
@Override
public void destroyItem(ViewGroupcontainer, int position, Object object) {
}
//此方法用来显示tab上的名字
@Override
public CharSequence getPageTitle(intposition) {
return titles[position %titles.length];
}
public List<Fragment> getFragments(){
return fragments;
}
public void setFragments(List<Fragment> fragments) {
this.fragments = fragments;
}
}
~~~
该Adapter中我们重写了getPageTitle()方法,用来显示Tab的标题。
3.3.下面就是具体的Fragment(TabInfoFragment)了,该Fragment中,我们初始化ViewPager,TabLayout以及自定义器适配器,Fragment页面和显示的Tab标题。
最终我们把适配器和ViewPager进行绑定,TabLayout和ViewPager进行绑定即可。
~~~
public class TabInfoFragment extends Fragment {
private String[]titles=new String[]{"全部","氪TV","O2O","新硬件","Fun!!","企业服务","Fit&Health","在线教育","互联网金融","大公司","专栏","新产品"};
private View mView;
private TabLayout tab_layout;
private ViewPager info_viewpager;
private List<Fragment> fragments;
private CNKFixedPagerAdapter mPagerAdater;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if(mView==null){
mView=inflater.inflate(R.layout.tab_info_fragment_layout,container,false);
initViews();
initValidata();
}
return mView;
}
private void initViews(){
tab_layout=(TabLayout)mView.findViewById(R.id.tab_layout);
info_viewpager=(ViewPager)mView.findViewById(R.id.info_viewpager);
}
private void initValidata(){
fragments=new ArrayList<>();
for(int i=0;i<12;i++){
OneFragment oneFragment=new OneFragment();
Bundle bundle=new Bundle();
bundle.putString("extra",titles[i]);
oneFragment.setArguments(bundle);
fragments.add(oneFragment);
}
//创建Fragment的 ViewPager 自定义适配器
mPagerAdater=new CNKFixedPagerAdapter(getChildFragmentManager());
//设置显示的标题
mPagerAdater.setTitles(titles);
//设置需要进行滑动的页面Fragment
mPagerAdater.setFragments(fragments);
info_viewpager.setAdapter(mPagerAdater);
tab_layout.setupWithViewPager(info_viewpager);
//设置Tablayout
//设置TabLayout模式 -该使用Tab数量比较多的情况
tab_layout.setTabMode(TabLayout.MODE_SCROLLABLE);
}
}
~~~
相信大家已经看到该代码的最后有一句:
~~~
tab_layout.setTabMode(TabLayout.MODE_SCROLLABLE);
~~~
该用来设置Tablayout的模式,除了上面的默认之外还有一个模式如下:
~~~
tab_layout.setTabMode(TabLayout.MODE_FIXED);
~~~
两者的区别如下,如果Tab数量比较多的情况下,最少用上面那个,Tab标签可以左右滑动显示。
3.4.运行效果如下:
![](https://box.kancloud.cn/2016-01-18_569c8ec7110d4.jpg)
## (四).Tab升级版改造:
上面的效果是属于基础版本直接Tab显示标题就结束了,有时候不会达到我们的要求Tab标签上面显示图标。那么现在我们对其进行改造一下可以让TabLayout打造的Tab既能显示图标又能显示文字标题信息。该主要采用Tab的以下方法实现:
~~~
tab.setCustomView(view); tab添加的自定义布局
~~~
4.1.首先对于Tab Item每一项我们需要定义一个布局文件:
~~~
<?xmlversion="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<ImageView
android:src="@mipmap/ic_launcher"
android:layout_width="15dp"
android:layout_height="15dp"
android:id="@+id/imageView"
android:layout_gravity="center_horizontal"
/>
<TextView
android:text="Item 01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView"
android:layout_gravity="center_horizontal"
/>
</LinearLayout>
~~~
该布局文件很简单,上下布局图标和标题
4.2.然后我们需要在CNKFixedPagerAdapter中进行以下修改:先前我们是通过重写public CharSequence getPageTitle(int position)该方法来显示标题的,那么现在我们需要删掉或者注释掉该方法,然后新增一个getTabView()方法来实时创建Tab Item的布局然后绑定数据:
~~~
/**
* 添加getTabView的方法,来进行自定义Tab的布局View
* @param position
* @return
*/
public View getTabView(int position){
mInflater=LayoutInflater.from(FDApplication.getInstance());
Viewview=mInflater.inflate(R.layout.tab_item_layout,null);
TextView tv= (TextView)view.findViewById(R.id.textView);
tv.setText(titles[position]);
ImageView img = (ImageView)view.findViewById(R.id.imageView);
img.setImageResource(R.mipmap.ic_launcher);
return view;
}
~~~
4.3.这些步骤做完了之后,在主Fragment(TabInfoFragment)中对Tablayout中每一项Tab作如下设置即可:获取到每一项Tab,然后给该Tab设置自定义布局调用tab.setCustomView()方法。
~~~
//设置自定义Tab--加入图标的demo
for(int i=0;i<12;i++){
TabLayout.Tab tab =tab_layout.getTabAt(i);
tab.setCustomView(mPagerAdater.getTabView(i));
}
~~~
4.4.运行结果如下:
![](https://box.kancloud.cn/2016-01-18_569c8ec73a84e.jpg)
## (五).最后总结
今天我们通过Android Design支持库TabLayout组件实现了仿照网易新闻客户端首页的页面滑动和顶部Tab效果。希望对大家有所帮助使用以前的方式虽然也可以显示这样的效果,不过技术在发展嘛,紧跟时代潮流吧~嘿嘿。
本次实例代码因为比较多,重点核心代码已经贴出来。不过实例注释过的全部代码已经上传到Github项目中了。同时欢迎大家去Github站点进行clone或者fork浏览整个开源快速开发框架项目~
[https://github.com/jiangqqlmj/FastDev4Android](https://github.com/jiangqqlmj/FastDev4Android)
- 前言
- Android快速开发框架介绍(一)
- Android首页图片自动无限循环轮播Gallery+FlowIndicator(二)
- Android 列表下拉刷新组件PullToRefreshListView使用(三)
- Android 数据缓存器ACache的详解和使用(四)
- Android崩溃异常捕捉CustomCrash,提升用户体验(五)
- Android实现沉浸式状态栏(六)
- AndroidAnnnotations注入框架介绍和Android Studios基本配置(七)
- AndroidAnnnotations注入框架的工作原理(八)
- AndroidAnnnotations注入框架使用之注入组件Components(九)
- AndroidAnnnotations注入框架使用之Injection标签详解(十)
- AndroidAnnnotations注入框架使用之事件绑定Event Binding(十一)
- AndroidAnnnotations注入框架使用之线程处理Threading(十二)
- AndroidAnnnotations注入框架使用之第三方框架集成RoboGuice(十三)
- AndroidAnnnotations注入框架使用之第三方框架集成Otto事件总线(十四)
- AndroidAnnnotations注入框架使用之第三方框架集成OrmLite(十五)
- AndroidAnnnotations注入框架使用之最佳实践之Adapters和lists(十六)
- AndroidAnnnotations注入框架使用之最佳实践SharedPreferences(十七)
- Android MVP开发模式详解(十九)
- 消息总线EventBus的基本使用(二十)
- 消息总线EventBus源码分析以及与Otto框架对比(二十一)
- 列表头生成带文本或者字母的图片开源库TextDrawable使用和详解(二十二)
- 重写WebView网页加载以及JavaScript注入详解(二十三)
- BaseAdapterHelper的基本使用介绍,让你摆脱狂写一堆Adapter烦恼(二十四)
- BaseAdapterHelper详解源码分析,让你摆脱狂写一堆Adapter烦恼(二十五)
- Volley完全解析之基础使用(二十六)
- Volley完全解析之进阶最佳实践与二次封装(二十七)
- RecyclerView完全解析,让你从此爱上它(二十八)
- RecyclerView完全解析之打造新版类Gallery效果(二十九)
- RecyclerView完全解析之结合AA(Android Annotations)注入框架实例(三十)
- RecyclerView完全解析之下拉刷新与上拉加载SwipeRefreshLayout(三十一)
- CardView完全解析与RecyclerView结合使用(三十二)
- 神器ViewDragHelper完全解析,妈妈再也不担心我自定义ViewGroup滑动View操作啦~(三十三)
- 神器ViewDragHelper完全解析之详解实现QQ5.X侧滑酷炫效果(三十四)
- 实例解析之SwipeRefreshLayout+RecyclerView+CardView(三十五)
- HorizontalScrollView,Fragment,FragmentStatePagerAdapter打造网易新闻Tab及滑动页面效果(三十六)
- Android Design支持库TabLayout打造仿网易新闻Tab标签效果(三十七)
- 打造QQ6.X最新版本侧滑界面效果(三十八)