## (一).前言:
仿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'
~~~

## (三).效果實現:
我們現在需要仿照網易新聞(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.運行效果如下:

## (四).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.運行結果如下:

## (五).最后總結
今天我們通過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最新版本側滑界面效果(三十八)