1. 程式人生 > >Android 為ViewPager新增滑動指示器(2)

Android 為ViewPager新增滑動指示器(2)

上一篇博文使用了開源庫PagerSlidingTabStrip來實現ViewPager的滑動指示器
其實Google官方的Android Support Design包也提供了TabLayout來實現滑動指示器的效果

TabLayout的使用方法也十分簡單,而且官方推出的控制元件一般也比較可靠吧~
使用前需要先匯入Android Support Design包

這裡寫圖片描述

這裡以我昨天寫的博文:為ViewPager新增滑動指示器 中介紹的ViewPager為基礎,所以一些重複的程式碼我就不再貼出來了

activity_main.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" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.czy.myapplication.MainActivity"> <android.support.design.widget.TabLayout
android:id="@+id/tabLayout" android:layout_width="match_parent" android:layout_height="wrap_content" />
<android.support.v4.view.ViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="0px" android:layout_weight
="1" />
</LinearLayout>

僅包含一個TabLayout和一個ViewPager

修改MainActivity的onCreate方法,將TabLayout 與ViewPager繫結

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        viewPager = (ViewPager) findViewById(R.id.viewPager);
        fragmentList = new ArrayList<>();
        Tab1 tab1 = new Tab1();
        Tab2 tab2 = new Tab2();
        Tab3 tab3 = new Tab3();
        fragmentList.add(tab1);
        fragmentList.add(tab2);
        fragmentList.add(tab3);
        PagerAdapter adapter = new PagerAdapter(MainActivity.this, fragmentList, getSupportFragmentManager());
        viewPager.setAdapter(adapter);

        TabLayout tabLayout = (TabLayout) findViewById(R.id.tabLayout);
        tabLayout.setupWithViewPager(viewPager);
        tabLayout.setTabMode(TabLayout.MODE_FIXED);
    }

執行效果如下:

這裡寫圖片描述

可以看到在切換的過程中標籤顏色會有所變化

我們可以來自定義TabLayout的style屬性

首先開啟style.xml檔案,自定義一個style,繼承於Widget.Design.TabLayout

<style name="CustomTabLayout" parent="Widget.Design.TabLayout"></style>

Widget.Design.TabLayout即TabLayout使用的style檔案,我們就要來重寫其屬性
此時CustomTabLayout標籤還為空,那如何知道我們可以設定哪些屬性呢?

方法很簡單,按住ctrl鍵,滑鼠點選Widget.Design.TabLayout,即可看到其宣告

    <style name="Widget.Design.TabLayout" parent="Base.Widget.Design.TabLayout">
        <item name="tabGravity">fill</item>
        <item name="tabMode">fixed</item>
    </style>

可以看到其繼承於Base.Widget.Design.TabLayout,再來點選進入檢視

<style name="Base.Widget.Design.TabLayout" parent="android:Widget">
        <item name="tabMaxWidth">@dimen/design_tab_max_width</item>
        <item name="tabIndicatorColor">?attr/colorAccent</item>
        <item name="tabIndicatorHeight">2dp</item>
        <item name="tabPaddingStart">12dp</item>
        <item name="tabPaddingEnd">12dp</item>
        <item name="tabBackground">?attr/selectableItemBackground</item>
        <item name="tabTextAppearance">@style/TextAppearance.Design.Tab</item>
        <item name="tabSelectedTextColor">?android:textColorPrimary</item>
    </style>

這些item即是我們可以改寫的屬性了

<style name="CustomTabLayout" parent="Widget.Design.TabLayout">
        <!--指示器的顏色-->
        <item name="tabIndicatorColor">#ec2727</item>
        <!--tab的最大寬度-->
        <item name="tabMaxWidth">150dp</item>
        <!--指示器的高度-->
        <item name="tabIndicatorHeight">2dp</item>
        <!--左padding值-->
        <item name="tabPaddingStart">8dp</item>
        <!--右padding值-->
        <item name="tabPaddingEnd">8dp</item>
        <!--被選中tab的背景-->
        <item name="tabBackground">?attr/selectableItemBackground</item>
        <!--tab標題的文字風格-->
        <item name="tabTextAppearance">@style/TextAppearance.Design.Tab</item>
        <!--被選中tab的文字顏色-->
        <item name="tabSelectedTextColor">#ea436cf1</item>
    </style>


    <style name="TextAppearance.Design.Tab" parent="TextAppearance.AppCompat.Button">
        <item name="android:textSize">20sp</item>
        <item name="android:textColor">#f26a52</item>
        <item name="textAllCaps">false</item>
    </style>

以上的屬性作用都有註釋,比較容易理解

效果圖如下:

這裡寫圖片描述

效果還是可以的~

此外,也可以為Tab標籤設定圖示

首先,需要先來定義每個Tab標籤使用的佈局檔案,包括圖示以及標題

tab_item.xml

<?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">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_gravity="center" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center" />

</LinearLayout>

修改PagerAdapter

先宣告三張需要用到的圖片資源

private int[] imageResId = {
            R.mipmap.ic_launcher,
            R.mipmap.ic_launcher,
            R.mipmap.ic_launcher
    };

然後再來定義一個獲取Tab標籤的方法

public View getTabView(int position) {
        View view = LayoutInflater.from(context).inflate(R.layout.tab_item, null);
        TextView tv = (TextView) view.findViewById(R.id.textView);
        tv.setText(titles[position]);
        ImageView img = (ImageView) view.findViewById(R.id.imageView);
        img.setImageResource(imageResId[position]);
        return view;
    }

這裡需要用到上下文Context,所以需要修改建構函式,傳入一個Context

public PagerAdapter(Context context, List<Fragment> fragmentList, FragmentManager fm) {
        super(fm);
        this.context = context;
        this.fragmentList = fragmentList;
    }

回到MainActivity,為TabLayout的每一個Tab設定一個自定義View

        TabLayout tabLayout = (TabLayout) findViewById(R.id.tabLayout);
        tabLayout.setupWithViewPager(viewPager);
        tabLayout.setTabMode(TabLayout.MODE_FIXED);

        for (int i = 0; i < tabLayout.getTabCount(); i++) {
            TabLayout.Tab tab = tabLayout.getTabAt(i);
            tab.setCustomView(adapter.getTabView(i));
        }

效果圖:
這裡寫圖片描述

圖示加標題的效果實現了,不過就有了一個新問題,就是原先選中Tab後相應的標題會改變顏色,在這裡卻失效了,因為這裡使用的是自定義的TextView
所以還需要再來進行一點修改

在drawable資料夾下新建一個item_color.xml檔案,設定TextView的樣式

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 沒有焦點時的字型顏色 -->
    <item android:color="#130101" android:state_selected="false" />
    <!--選中時的字型顏色  -->
    <item android:color="#e9140d" android:state_selected="true" />
</selector>

然後,讓TextView引用之

    <TextView
        android:textColor="@drawable/item_color"
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center" />

效果圖:
這裡寫圖片描述

可以看到變色效果又回來了