TabLayout+ViewPager 實現tab切換

在項目開發中很多場景都會碰到tab欄切換的效果,實現的思路也有很多種,tabhost+fragment,radionbtton+viewpager等方式都可以實現,這裏就說下tablayout+viewpager的實現方式;tablayout是android5.0推出來的一個MaterialDesign風格的控件,是專門用來實現tab欄效果的;功能強大,使用方便靈活;

1、引入依賴庫

compile 'com.android.support:design:25.3.1'
compile 'com.android.support:support-v4:25.3.1'

2、xml佈局文件中使用

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.mdtablayout.MainActivity">
    <android.support.design.widget.TabLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabIndicatorColor="@color/colorAccent"
        app:tabTextColor="@android:color/black"
        app:tabSelectedTextColor="@color/colorAccent"
        app:tabMode="scrollable"
        app:tabGravity="fill"/>
    <android.support.v4.view.ViewPager
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>

tablayout提供了很多的屬性可以設置:

app:tabIndicatorColor    指示器顏色
app:tabTextColor         tab欄字體顏色
app:tabSelectedTextColor tab欄字體被選顏色
app:tabIndicatorHeight   指示器高度
app:tabBackground        tab背景顏色
app:tabMaxWidth          tab欄最大寬度
app:tabTextAppearance    tab欄字體樣式
app:tabMinWidth          tab欄最小寬度
......

這些屬性可以下xml中設置,也可以使用代碼進行設置;需要注意這兩個屬性:

app:tabMode="";有scrollable和fixed兩個屬性值
scrollable:可滑動;
fixed:不能滑動,平分tabLayout寬度;

app:tabGravity="";有center和fill兩個屬性值
fill:tabs平均填充整個寬度;
center:tab居中顯示;

3、設置tablayout和viewpager,並將tablayout和viewpager進行關聯
在設置tablayout和viewpager,並將tablayout和viewpager進行關聯有兩中方式可以實現:
方式一:
3.1、TabLayout和Viewpager關聯

tablayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                //tab被選的時候回調
                viewpager.setCurrentItem(tab.getPosition(),true);
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                //tab未被選擇的時候回調
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {
                //tab重新選擇的時候回調
            }
        });

3.2、ViewPager滑動關聯tabLayout

3.3、設置tabLayout的標籤來自於PagerAdapter

tablayout.setTabsFromPagerAdapter(tabAdapter);

3.4、ViewPager設置適配器

viewpager.setAdapter(tabAdapter);

方式二:
4.1、viewpager設置適配器

viewpager.setAdapter(tabAdapter);

4.2、tablayout和viewpager相互關聯,並設置tablayout文字

tablayout.setupWithViewPager(viewpager);

使用第二種方式需要注意的是setupWithViewPager();方法的調用必須在viewpager設置完適配器後調用,如果在設置適配器之前調用會拋異常,至於爲什麼會拋異常,後面tablayout的源碼會說到;這樣tab欄切換效果就實現了:

è¿éåå¾çæè¿°

在上面說到了tablayout的tabMode和tabGravity兩個屬性,將這個兩個屬性對應的值做下修改就可以實現一些其他的效果,這裏將tablayout對應的值修改爲fixed(不可滑動),tabGravity的值修改爲center(tab居中顯示),將tab欄的數量改爲兩個;效果如下:

è¿éåå¾çæè¿°

上面這些效果都是用tablayout實現的頂部tab欄切換,tablayout照樣可以實現底部tab欄切換的效果;

修改xml佈局文件,將tablayout和viewpager的位置互換,並設置viewpager的weight,同時將tablayout的tabIndicatorHeight屬性值設爲0dp,將指示器隱藏掉,tabMode屬性值設置爲fixed,tabGravity的屬性值設置爲fill;

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.mdtablayout.MainActivity">
    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"/>
    <android.support.design.widget.TabLayout
        android:id="@+id/tablayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabIndicatorColor="@color/colorAccent"
        app:tabTextColor="@android:color/black"
        app:tabSelectedTextColor="@color/colorAccent"
        app:tabMode="fixed"
        app:tabGravity="fill"
        android:background="@android:color/holo_orange_light"
        app:tabIndicatorHeight="0dp"/>
</LinearLayout>

其他的文件不用做改動,效果就可以實現了: 

è¿éåå¾çæè¿°

如果想在底部tab欄文字上面添加圖片實現類似微信那樣的效果也是可以的,在tablayout和viewpager關聯後,獲取tablayout的tab數量,並對數量進行遍歷獲取到每個tab,給每個tab設置相應的view就可以了;

//獲取當前tab數量
int tabCount = tablayout.getTabCount();
//遍歷循環tab數量
for(int i=0;i<tabCount;i++){
    //獲取每個tab
    TabLayout.Tab tab = tablayout.getTabAt(i);
    //通過相應的佈局文件獲取view
    View view = View.inflate(this, R.layout.tab_view, null);
    ImageView iv = (ImageView) view.findViewById(R.id.iv);
    TextView tv = (TextView) view.findViewById(R.id.tv);
    //設置tab欄文字
    tv.setText(tabList.get(i));
    //設置tab圖片
    iv.setImageResource(R.mipmap.message_icon);
    //給tab設置view
    tab.setCustomView(view);
}

這樣效果就實現了:

è¿éåå¾çæè¿°

源碼地址: 
http://download.csdn.net/detail/wangwo1991/9915302