天天看點

【FastDev4Android架構開發】Android Design支援庫TabLayout打造仿網易新聞Tab标簽效果(三十七)(一).前言:   (二).使用方式:   (三).效果實作:  (四).Tab更新版改造:   (五).最後總結

轉載請标明出處:

http://blog.csdn.net/developer_jiangqq/article/details/50158985

本文出自:【江清清的部落格】

(一).前言:   

           【好消息】個人網站已經上線運作,後面部落格以及技術幹貨等精彩文章會同步更新,請大家關注收藏:http://www.lcode.org

        仿36Kr用戶端開發過程中,因為他們網站上面的新聞文章分類比較多,是以我這邊還是打算模仿網易新聞APP的主界面新聞标簽Tab以及頁面滑動效果來進行實作。要實作的頂部的Tab标簽的效果有很多方法例如采用開源項目ViewPagerIndicator中的TabPageIndicator就可以實作。不過我們今天不講ViewPagerIndicator,我們來講一下Google今年釋出的TabLayout元件。在2015年的Google大會上,google釋出的新的Android Support Design庫,裡面也包含了幾個新的控件,那麼TabLayout就是其中一個。使用該元件我們可以很輕松的實作TabPageIndicator效果,并且該為官方的,可以向下相容很多版本而且可以更加統一Material Design效果。不過檢視TabLayout的源碼發現該元件也是繼承自HorizontalScrollView實作。

          使用HorizontalScrollView打造仿網易tab标簽效果,點選進入...

          本例子具體代碼已經上傳到下面的項目中,歡迎各位去star和fork一下。

         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'
           
【FastDev4Android架構開發】Android Design支援庫TabLayout打造仿網易新聞Tab标簽效果(三十七)(一).前言:   (二).使用方式:   (三).效果實作:  (四).Tab更新版改造:   (五).最後總結

(三).效果實作:  

          我們現在需要仿照網易新聞(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
 * 郵箱:[email protected]
 * 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.運作效果如下:

【FastDev4Android架構開發】Android Design支援庫TabLayout打造仿網易新聞Tab标簽效果(三十七)(一).前言:   (二).使用方式:   (三).效果實作:  (四).Tab更新版改造:   (五).最後總結

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

【FastDev4Android架構開發】Android Design支援庫TabLayout打造仿網易新聞Tab标簽效果(三十七)(一).前言:   (二).使用方式:   (三).效果實作:  (四).Tab更新版改造:   (五).最後總結

(五).最後總結

           今天我們通過Android  Design支援庫TabLayout元件實作了仿照網易新聞用戶端首頁的頁面滑動和頂部Tab效果。希望對大家有所幫助使用以前的方式雖然也可以顯示這樣的效果,不過技術在發展嘛,緊跟時代潮流吧~嘿嘿。

           本次執行個體代碼因為比較多,重點核心代碼已經貼出來。不過執行個體注釋過的全部代碼已經上傳到Github項目中了。同時歡迎大家去Github站點進行clone或者fork浏覽整個開源快速開發架構項目~

https://github.com/jiangqqlmj/FastDev4Android

尊重原創,轉載請注明:From Sky丶清(http://blog.csdn.net/developer_jiangqq) 侵權必究!

關注我的訂閱号,每天分享移動開發技術(Android/IOS),項目管理以及部落格文章!

【FastDev4Android架構開發】Android Design支援庫TabLayout打造仿網易新聞Tab标簽效果(三十七)(一).前言:   (二).使用方式:   (三).效果實作:  (四).Tab更新版改造:   (五).最後總結

關注我的微網誌,可以獲得更多精彩内容

【FastDev4Android架構開發】Android Design支援庫TabLayout打造仿網易新聞Tab标簽效果(三十七)(一).前言:   (二).使用方式:   (三).效果實作:  (四).Tab更新版改造:   (五).最後總結

繼續閱讀