什么是TabLayout
上圖中,我們可以看到扬跋,該頁(yè)面分成三個(gè)頁(yè)簽阶捆,每個(gè)頁(yè)簽對(duì)應(yīng)不同的內(nèi)容,如果讓我們來(lái)實(shí)現(xiàn)布局的話钦听,我們會(huì)很容易地想到布局為一個(gè)頁(yè)簽指示器+ViewPager洒试,以前,相信各位大多使用的是GitHub上的開源框架PagerSlidingTabTrip來(lái)實(shí)現(xiàn)指示器的效果朴上,而如今垒棋,Android中也有自帶這種指示器的控件TabLayout,TabLayout存在于android design庫(kù)中,它提供了一個(gè)水平的布局來(lái)展示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="頁(yè)簽1"
/>
<android.support.design.widget.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="頁(yè)簽2"
/>
<android.support.design.widget.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="頁(yè)簽3"
/>
</android.support.design.widget.TabLayout>
</LinearLayout>
代碼中我們可以看到衣撬,<TabLayout></TabLayout>之間包裹著TabItem,也就是每個(gè)頁(yè)簽的配置乖订,我們這里只是簡(jiǎn)單地配置了文字,先運(yùn)行下看看效果:
3.如何設(shè)置頁(yè)簽的點(diǎn)擊事件
在java文件中具练,我們根據(jù)id找到TabLayout,為其添加頁(yè)簽選中的監(jiān)聽垢粮,當(dāng)選中標(biāo)簽的時(shí)候,彈出對(duì)應(yīng)標(biāo)簽的文字:
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) {
}
});
效果如圖:
動(dòng)態(tài)創(chuàng)建Tab
上面我們簡(jiǎn)單演示了在布局文件中配置了TabLayout和對(duì)應(yīng)的頁(yè)簽TabItem靠粪,接下來(lái)我們演示如何動(dòng)態(tài)創(chuàng)建頁(yè)簽蜡吧,修改布局文件:
<?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,并為其動(dòng)態(tài)添加Tab:
public class TabLayoutActivity extends AppCompatActivity {
private String[] titles = new String[]{
"體育",
"社會(huì)",
"新聞"
};
@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();//創(chuàng)建tab
tab.setText(titles[i]);//設(shè)置文字
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設(shè)置圖標(biāo)
Tab的創(chuàng)建是通過(guò)調(diào)用TabLayout的newTab()方法占键,創(chuàng)建出來(lái)的Tab對(duì)象即頁(yè)簽對(duì)象昔善,除了setText()方法設(shè)置文字外,還可以設(shè)置對(duì)應(yīng)的圖標(biāo)畔乙,通過(guò)調(diào)用setIcon()方法君仆,就可以設(shè)置Tab的圖標(biāo):
for (int i = 0; i < titles.length; i++) {
TabLayout.Tab tab = tabLayout.newTab();//創(chuàng)建tab
tab.setText(titles[i]);//設(shè)置文字
tab.setIcon(R.mipmap.ic_launcher);//設(shè)置圖標(biāo)
tabLayout.addTab(tab);//添加到tabLayout中
}
效果如圖:
設(shè)置更加美觀的Tab
如果不喜歡圖標(biāo)在頁(yè)簽的上面,有別的需求牲距,比如圖標(biāo)在頁(yè)簽的左邊返咱,那么這時(shí),可以使用Tab的setCustomView(View view)方法牍鞠,可以通過(guò)布局填充器將自己布局好的xml填充成View對(duì)象,然后設(shè)置進(jìn)去咖摹,就可以實(shí)現(xiàn)更加美觀的頁(yè)簽了,有興趣的同學(xué)可以試試看难述。
修改TabLayout的樣式
Tablayout支持定制化修改萤晴,提供了不少自定義屬性供開發(fā)者進(jìn)行設(shè)置。有以下屬性支持修改:
tabBackground="" tablayout的背景顏色
tabIndicatorColor="" 指示器的顏色
tabIndicatorHeight="" 指示器的高度
tabGravity="" 指示器的位置
tabMode="" 顯示模式
tabSelectedTextColor="" 選中時(shí)文字顏色
tabTextColor="" 未選中時(shí)文字顏色
tabTextAppearance="" 字體外觀
tabMaxWidth="" tab最大寬度
tabMinWidth="" tab最小寬度
tabPadding="" tab內(nèi)邊距
自定義TabLayout:
下面我們簡(jiǎn)單修改下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"
/>
這里我們?yōu)門abLayout設(shè)置了藍(lán)色的背景色,設(shè)置了指示器的高度和顏色(灰色)攀芯,設(shè)置了選中時(shí)文字的顏色為淺藍(lán)色屯断,未選中時(shí)為白色,還設(shè)置了字體的外觀侣诺,字體的外觀設(shè)置需要在style.xml中定義樣式殖演,如下:
<style name="TabTextStyle" parent="TextAppearance.Design.Tab">
<item name="android:textSize">16sp</item>
</style>
這里定義了字體的大小,樣式中還可以設(shè)置字體其他外觀紧武,比如設(shè)置字體是否加粗等剃氧。
看一下自定義的TabLayout效果:
可以看到,效果和我們?cè)O(shè)置的一樣阻星。
Tab的位置和顯示模式(tabGravity和tabMode)
1.tabGravity有兩個(gè)值可選朋鞍,分別是center(居中)和fill(填滿),默認(rèn)tabGravity="fill",填滿妥箕,我們將它設(shè)置為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的寬度沒(méi)有填滿滥酥,而且整個(gè)TabLayout居中顯示。
2.當(dāng)有很多個(gè)tab畦幢,多到屏幕放不下的時(shí)候坎吻,比如今日頭條的TabLayout,我們需要將TabLayout的顯示模式tabMode更改為scrollable宇葱,這樣整個(gè)TabLayout就可以左右滑動(dòng)瘦真,TabLayout默認(rèn)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"
/>
添加多一些頁(yè)簽:
String[] channels = getResources().getStringArray(R.array.channel);
for (int i = 0; i < channels.length; i++) {
TabLayout.Tab tab = tabLayout.newTab();//創(chuàng)建tab
tab.setText(channels[i]);//設(shè)置文字
tabLayout.addTab(tab);//添加到tabLayout中
}
channel是一個(gè)定義在xml中的string-array:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="channel">
<item>推薦</item>
<item>視頻</item>
<item>熱點(diǎn)</item>
<item>社會(huì)</item>
<item>娛樂(lè)</item>
<item>科技</item>
<item>汽車</item>
<item>體育</item>
<item>財(cái)經(jīng)</item>
<item>軍事</item>
<item>國(guó)際</item>
<item>時(shí)尚</item>
<item>游戲</item>
<item>旅游</item>
<item>歷史</item>
<item>探索</item>
<item>美食</item>
<item>育兒</item>
<item>養(yǎng)生</item>
<item>故事</item>
<item>美文</item>
</string-array>
</resources>
運(yùn)行的效果如下:
可以看到TabLayout有許多Tab,且可以左右滑動(dòng)诸尽。需要注意的是原杂,當(dāng)設(shè)置tabMode為scrollable時(shí),此時(shí)設(shè)置tabGravity已經(jīng)無(wú)效您机,無(wú)論設(shè)置為哪個(gè)值穿肄,它都是填滿的效果。
TabLayout結(jié)合ViewPager
TabLayout + ViewPager 在開發(fā)中經(jīng)常使用到际看,即上面顯示頁(yè)簽咸产,下面展示不同的fragment,就如今日頭條仲闽,現(xiàn)在我們仿造今日頭條的首頁(yè)脑溢,演示下如果使用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文件中焚志,設(shè)置TabLayout和ViewPager關(guān)聯(lián)起來(lái):
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設(shè)置adapter
mTabLayout.setupWithViewPager(mVpContent);//將TabLayout和ViewPager關(guān)聯(lián)
}
}
運(yùn)行的效果如下:
可以看到,TabLayout和ViewPager已經(jīng)關(guān)聯(lián)起來(lái)畏鼓,當(dāng)點(diǎn)擊頁(yè)簽的時(shí)候酱酬,ViewPager會(huì)切換到對(duì)應(yīng)的fragment,滑動(dòng)ViewPager,對(duì)應(yīng)頁(yè)簽也會(huì)跟著改變云矫。
這里需要注意的是膳沽,實(shí)現(xiàn)ViewPager的adapter時(shí),需要重寫Adapter的getPageTitle()方法让禀,返回對(duì)應(yīng)頁(yè)簽的內(nèi)容挑社,這樣TabLayout才會(huì)有對(duì)應(yīng)的頁(yè)簽。
好了巡揍,到這里關(guān)于TabLayout的介紹就到此為止了痛阻,想看源碼的話,可以點(diǎn)擊以下鏈接: