MaterialDesign學習篇(四),如何使用TabLayout

什么是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的介紹就到此為止了,想看源碼的話,可以點擊以下鏈接:

https://github.com/chaychan/MaterialDesignExercise

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,556評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,463評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,009評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,778評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,218評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,436評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,969評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,795評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,993評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,229評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,659評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,917評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,687評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,990評論 2 374

推薦閱讀更多精彩內容