TabLayout是Android Design Support Library的組件,可以很方便的寫出頂部導航欄比以前那個什麼TabHost好用多了,因爲是Design Support Library下的控件,所以使用它要引入相關依賴
implementation 'com.android.support:design:26.1.0'
**注意**Android studio 3.0以後,引入依賴關鍵詞變成了implementation
在之前版本的關鍵詞是 compile
本文最終實現的最終效果如下圖所示:
使用方法
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="scrollable" />
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
1.找到相應控件
mTabLayout = (TabLayout) findViewById(R.id.tabLayout);
mViewPager = (ViewPager) findViewById(R.id.viewPager);
2.創建tab項
//使用Tablayout的newTab()創建tab
TabLayout.Tab tab1 = mTabLayout.newTab()
//設置tab項顯示的文字
.setText("tab1");
TabLayout.Tab tab2 = mTabLayout.newTab().setText("tab2");
TabLayout.Tab tab3 = mTabLayout.newTab().setText("tab3");
說明: 創建Tab對象不能通過new 對象的方式,而是使用TabLayout
裏面的newTab()
的方式創建,查看源碼就可以知道Tab的構成方法是沒有修飾詞,也就是默認權限,它所在包以外都沒權限訪問。
3.將tab項添加到TabLayout中
mTabLayout.addTab(tab1);
mTabLayout.addTab(tab2);
mTabLayout.addTab(tab3);
運行效果如下
4.準備ViewPager數據
- 使用ViewPager前先要有一個它的適配器
public class TabPageAdapter extends FragmentPagerAdapter {
private List<Fragment> fragments;
public TabPageAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
}
- 向適配器中添加數據
fragments=new ArrayList<>();
//將提前寫好三個Fragment添加到集合中
fragments.add(new FirstFragment());
fragments.add(new SecondFragment());
fragments.add(new ThirdFragment());
//創建適配器
TabPageAdapter pageAdapter = new TabPageAdapter(getSupportFragmentManager(), fragments);
//設置ViewPager的適配器
mViewPager.setAdapter(pageAdapter);
- 把TabLayout和ViewPager組合,使用setupWithViewPager可以讓TabLayout和ViewPager聯動
mTabLayout.setupWithViewPager(mViewPager);
寫到這感覺應可以了吧
什麼情況,聯動效果出來了,但Tab項的字去哪了
查看setupWithViewPager
源碼發現,在ViewPager適配器不爲空的情況下,最終會調用populateFromPagerAdapter()
方法
void populateFromPagerAdapter() {
removeAllTabs();//移除tab添加的所有tab項
if (mPagerAdapter != null)
final int adapterCount = mPagerAdapter.getCount();
for (int i = 0; i < adapterCount; i++) {
//創建Tab項,把tab顯示的標題設置爲從獲取適配的getPageTitle的內容
addTab(newTab().setText(mPagerAdapter.getPageTitle(i)), false);
}
// Make sure we reflect the currently set ViewPager item
if (mViewPager != null && adapterCount > 0) {
final int curItem = mViewPager.getCurrentItem();
if (curItem != getSelectedTabPosition() && curItem < getTabCount()) {
selectTab(getTabAt(curItem));
}
}
}
}
從上面可以看出,我們之前向TabLayout添加的Tab項調用這個方法後都被移除了,它會重新創建新的Tab項,tab顯示的文字是從適配器getPageTitle()
獲取的 。上面我們寫適配器的時候沒有重寫適配器的getPageTitle()
方法 ,所以上面效果就是有Tab項但Tab項上沒有文字了,解決辦法就是重寫適配器的getPageTitle()
方法
public class TabPageAdapter extends FragmentPagerAdapter {
private List<Fragment> fragments;
private String[] tabNames;//tab選項名字
public TabPageAdapter(FragmentManager fm, List<Fragment> fragments,String[] tabNames) {
super(fm);
this.fragments = fragments;
this.tabNames=tabNames;
}
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
//重寫getPageTitle()方法
@Override
public CharSequence getPageTitle(int position) {
//返回tab選項的名字
return tabNames[position];
}
}
String[] mTabNames=new String[]{"tab1","tab2","tab3"};
TabPageAdapter pageAdapter = new TabPageAdapter(getSupportFragmentManager(), fragments,mTabNames);
這種方式tab選項不是我們自己創建的,如果想對tab項設置一下屬性,通過getTabAt(int index)
方法獲取tab對象進行一些設置就可以了
關於TabLayout的屬性設置
- 設置指示器樣式(設置顏色和高度)
app:tabIndicatorColor="#1565C0"
app:tabIndicatorHeight="4dp"
- 設置選擇時的字體顏色
app:tabSelectedTextColor="#9C27B0"
- 設置TabLayout顯示的模式(fixed or scrollable)
TabLayout默認爲fixed模式,將所有tab項都顯示出來,佔滿它的寬度
app:tabMode="fixed"
scrollable 模式,如果TabLayout不能將所有tab顯示,就可以滾動查看所有tab項
app:tabMode="scrollable"
TabLayout的監聽事件
mTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
//tab項選中狀態時執行
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
//tab項取消選中狀態時執行
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
//tab項選中狀態再次點擊時執行
}
});