在項目開發中很多場景都會碰到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); }
這樣效果就實現了: