什么是TabLayout
上圖中,我們可以看到,該頁面分成三個頁簽,每個頁簽對應不同的內容,如果讓我們來實現布局的話,我們會很容易地想到布局為一個頁簽指示器+ViewPager,以前,相信各位大多使用的是GitHub上的開源框架PagerSlidingTabTrip來實現指示器的效果,而如今,Android中也有自帶這種指示器的控件TabLayout,TabLayout存在于android design庫中,它提供了一個水平的布局來展示Tabs。
一 如何使用TabLayout
1.要使用TabLayout,首先要添加 android support design包的依賴,在app模塊的build.gradle中添加:
dependencies {
...
compile 'com.android.support:design:26.0.0-alpha1'
}
2.在布局文件的xml中,使用TabLayout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<android.support.design.widget.TabLayout
android:id="@+id/tab"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="頁簽1"
/>
<android.support.design.widget.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="頁簽2"
/>
<android.support.design.widget.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="頁簽3"
/>
</android.support.design.widget.TabLayout>
</LinearLayout>
代碼中我們可以看到,<TabLayout></TabLayout>之間包裹著TabItem,也就是每個頁簽的配置,我們這里只是簡單地配置了文字,先運行下看看效果:
3.如何設置頁簽的點擊事件
在java文件中,我們根據id找到TabLayout,為其添加頁簽選中的監聽,當選中標簽的時候,彈出對應標簽的文字:
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab);
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
Toast.makeText(TabLayoutActivity.this, tab.getText(), Toast.LENGTH_SHORT).show();
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
效果如圖:
動態創建Tab
上面我們簡單演示了在布局文件中配置了TabLayout和對應的頁簽TabItem,接下來我們演示如何動態創建頁簽,修改布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<android.support.design.widget.TabLayout
android:id="@+id/tab"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
在Activity中找到TabLayout,并為其動態添加Tab:
public class TabLayoutActivity extends AppCompatActivity {
private String[] titles = new String[]{
"體育",
"社會",
"新聞"
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tab_layout);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab);
for (int i = 0; i < titles.length; i++) {
TabLayout.Tab tab = tabLayout.newTab();//創建tab
tab.setText(titles[i]);//設置文字
tabLayout.addTab(tab);//添加到tabLayout中
}
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
Toast.makeText(TabLayoutActivity.this, tab.getText(), Toast.LENGTH_SHORT).show();
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
}
效果如圖:
為Tab設置圖標
Tab的創建是通過調用TabLayout的newTab()方法,創建出來的Tab對象即頁簽對象,除了setText()方法設置文字外,還可以設置對應的圖標,通過調用setIcon()方法,就可以設置Tab的圖標:
for (int i = 0; i < titles.length; i++) {
TabLayout.Tab tab = tabLayout.newTab();//創建tab
tab.setText(titles[i]);//設置文字
tab.setIcon(R.mipmap.ic_launcher);//設置圖標
tabLayout.addTab(tab);//添加到tabLayout中
}
效果如圖:
設置更加美觀的Tab
如果不喜歡圖標在頁簽的上面,有別的需求,比如圖標在頁簽的左邊,那么這時,可以使用Tab的setCustomView(View view)方法,可以通過布局填充器將自己布局好的xml填充成View對象,然后設置進去,就可以實現更加美觀的頁簽了,有興趣的同學可以試試看。
修改TabLayout的樣式
Tablayout支持定制化修改,提供了不少自定義屬性供開發者進行設置。有以下屬性支持修改:
tabBackground="" tablayout的背景顏色
tabIndicatorColor="" 指示器的顏色
tabIndicatorHeight="" 指示器的高度
tabGravity="" 指示器的位置
tabMode="" 顯示模式
tabSelectedTextColor="" 選中時文字顏色
tabTextColor="" 未選中時文字顏色
tabTextAppearance="" 字體外觀
tabMaxWidth="" tab最大寬度
tabMinWidth="" tab最小寬度
tabPadding="" tab內邊距
自定義TabLayout:
下面我們簡單修改下TabLayout提供修改的屬性,看看修改后是怎樣的效果,修改布局文件:
<android.support.design.widget.TabLayout
android:id="@+id/tab"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabBackground="@color/colorPrimary"
app:tabIndicatorColor="@android:color/darker_gray"
app:tabIndicatorHeight="5dp"
app:tabSelectedTextColor="@android:color/holo_blue_light"
app:tabTextColor="@android:color/white"
app:tabTextAppearance="@style/TabTextStyle"
/>
這里我們為TabLayout設置了藍色的背景色,設置了指示器的高度和顏色(灰色),設置了選中時文字的顏色為淺藍色,未選中時為白色,還設置了字體的外觀,字體的外觀設置需要在style.xml中定義樣式,如下:
<style name="TabTextStyle" parent="TextAppearance.Design.Tab">
<item name="android:textSize">16sp</item>
</style>
這里定義了字體的大小,樣式中還可以設置字體其他外觀,比如設置字體是否加粗等。
看一下自定義的TabLayout效果:
可以看到,效果和我們設置的一樣。
Tab的位置和顯示模式(tabGravity和tabMode)
1.tabGravity有兩個值可選,分別是center(居中)和fill(填滿),默認tabGravity="fill",填滿,我們將它設置為center,看下效果:
<android.support.design.widget.TabLayout
android:id="@+id/tab"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabBackground="@color/colorPrimary"
app:tabIndicatorColor="@android:color/darker_gray"
app:tabIndicatorHeight="5dp"
app:tabSelectedTextColor="@android:color/holo_blue_light"
app:tabTextColor="@android:color/white"
app:tabTextAppearance="@style/TabTextStyle"
app:tabGravity="center"
/>
可以看到TabLayout的寬度沒有填滿,而且整個TabLayout居中顯示。
2.當有很多個tab,多到屏幕放不下的時候,比如今日頭條的TabLayout,我們需要將TabLayout的顯示模式tabMode更改為scrollable,這樣整個TabLayout就可以左右滑動,TabLayout默認tabMode為fixed(固定),我們將其修改為scrollable:
<android.support.design.widget.TabLayout
android:id="@+id/tab"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabBackground="@color/colorPrimary"
app:tabIndicatorColor="@android:color/darker_gray"
app:tabIndicatorHeight="5dp"
app:tabSelectedTextColor="@android:color/holo_blue_light"
app:tabTextColor="@android:color/white"
app:tabTextAppearance="@style/TabTextStyle"
app:tabGravity="center"
app:tabMode="scrollable"
/>
添加多一些頁簽:
String[] channels = getResources().getStringArray(R.array.channel);
for (int i = 0; i < channels.length; i++) {
TabLayout.Tab tab = tabLayout.newTab();//創建tab
tab.setText(channels[i]);//設置文字
tabLayout.addTab(tab);//添加到tabLayout中
}
channel是一個定義在xml中的string-array:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="channel">
<item>推薦</item>
<item>視頻</item>
<item>熱點</item>
<item>社會</item>
<item>娛樂</item>
<item>科技</item>
<item>汽車</item>
<item>體育</item>
<item>財經</item>
<item>軍事</item>
<item>國際</item>
<item>時尚</item>
<item>游戲</item>
<item>旅游</item>
<item>歷史</item>
<item>探索</item>
<item>美食</item>
<item>育兒</item>
<item>養生</item>
<item>故事</item>
<item>美文</item>
</string-array>
</resources>
運行的效果如下:
可以看到TabLayout有許多Tab,且可以左右滑動。需要注意的是,當設置tabMode為scrollable時,此時設置tabGravity已經無效,無論設置為哪個值,它都是填滿的效果。
TabLayout結合ViewPager
TabLayout + ViewPager 在開發中經常使用到,即上面顯示頁簽,下面展示不同的fragment,就如今日頭條,現在我們仿造今日頭條的首頁,演示下如果使用TabLayout + ViewPager。
首先,在布局文件中配置TabLayout和ViewPager:
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<android.support.design.widget.TabLayout
android:id="@+id/tab"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabBackground="@color/colorPrimary"
app:tabIndicatorColor="@android:color/darker_gray"
app:tabIndicatorHeight="5dp"
app:tabSelectedTextColor="@android:color/holo_blue_light"
app:tabTextColor="@android:color/white"
app:tabTextAppearance="@style/TabTextStyle"
app:tabGravity="center"
app:tabMode="scrollable"
/>
<android.support.v4.view.ViewPager
android:id="@+id/vp_content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
</LinearLayout>
java文件中,設置TabLayout和ViewPager關聯起來:
public class TabLayoutActivity extends AppCompatActivity {
private TabLayout mTabLayout;
private ViewPager mVpContent;
private List<ContentFragment> mFragments = new ArrayList<>();
private String[] mTitles;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tab_layout);
initView();
initData();
initListener();
}
private void initView() {
mTabLayout = (TabLayout) findViewById(R.id.tab);
mVpContent = (ViewPager) findViewById(R.id.vp_content);
}
private void initData() {
mTitles = getResources().getStringArray(R.array.channel);
for (int i = 0; i < mTitles.length; i++) {
ContentFragment fragment = new ContentFragment();
Bundle bundle = new Bundle();
bundle.putString(ContentFragment.TEXT, mTitles[i]);
fragment.setArguments(bundle);
mFragments.add(fragment);//添加到fragment中
}
}
private void initListener() {
TabAdapter tabAdapter = new TabAdapter(getSupportFragmentManager(), mFragments, mTitles);
mVpContent.setAdapter(tabAdapter);//為viewPager設置adapter
mTabLayout.setupWithViewPager(mVpContent);//將TabLayout和ViewPager關聯
}
}
運行的效果如下:
可以看到,TabLayout和ViewPager已經關聯起來,當點擊頁簽的時候,ViewPager會切換到對應的fragment,滑動ViewPager,對應頁簽也會跟著改變。
這里需要注意的是,實現ViewPager的adapter時,需要重寫Adapter的getPageTitle()方法,返回對應頁簽的內容,這樣TabLayout才會有對應的頁簽。
好了,到這里關于TabLayout的介紹就到此為止了,想看源碼的話,可以點擊以下鏈接: