如何使用 ViewPager + TabLayout

如何使用 ViewPager + TabLayout

情境

如何使用 TabLayout如何使用 ViewPager
這兩篇文章詳細描述了兩種元件的操作方法
我們可以嘗試將兩種工具合併在一起

所呈現的效果如下



完整程式碼

你也可以到 GitHub 上面觀看或下載完整的程式碼

程式碼說明

首先在 activity_main.xml 放上 ViewPager 以及 TabLayout

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.givemepss.viewpagertablayoutdemo.MainActivity">

    <android.support.design.widget.TabLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/tabs"
         />
    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_below="@id/tabs"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</RelativeLayout>

由於 TabLayout 屬於 design library 的東西
因此我們在Gradle要加入
下面的版本會隨著你使用的 Android SDK 版本而有所變化

compile 'com.android.support:design:22.2.0'

MainActivity.java 主程式當中宣告了一個 TabLayout 以及一個 ViewPager 的元件
透過 activity_main.xml 的佈局
我們將這兩個元件利用 findViewById 的方式來變成物件
之後就可以使用這兩個元件來進行操作

public class MainActivity extends AppCompatActivity {
    private TabLayout mTablayout;
    private ViewPager mViewPager;
    private List<PageView> pageList;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();
        initView();
    }

    private void initData() {
        pageList = new ArrayList<>();
        pageList.add(new PageOne(MainActivity.this));
        pageList.add(new PageTwo(MainActivity.this));
        pageList.add(new PageThree(MainActivity.this));
    }

    private void initView() {
        mTablayout = (TabLayout) findViewById(R.id.tabs);
        mTablayout.addTab(mTablayout.newTab().setText("Page one"));
        mTablayout.addTab(mTablayout.newTab().setText("Page two"));
        mTablayout.addTab(mTablayout.newTab().setText("Page three"));

        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(new SamplePagerAdapter());
        initListener();
    }

    private void initListener() {
        mTablayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                mViewPager.setCurrentItem(tab.getPosition());
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });
        mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(mTablayout));
    }

    private class SamplePagerAdapter extends PagerAdapter {

        @Override
        public int getCount() {
            return pageList.size();
        }

        @Override
        public boolean isViewFromObject(View view, Object o) {
            return o == view;
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            container.addView(pageList.get(position));
            return pageList.get(position);
        }
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View) object);
        }

    }
}

大致上跟如何使用TabLayout 以及如何使用ViewPager 這兩個範例差不多
比較有分別的是 ViewPager 與 TabLayout 要進行連動
所以多了一個 initListener 的方法
如何使用TabLayout講到我們會透過 addOnPageChangeListener 以及 setOnTabSelectedListener 這兩個方法讓 ViewPager 以及 TabLayout 進行連動
因此你可以看到使用以下的方法
也可以跟 ViewPager 和 TabLayout 的連動綁在一起

mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(mTabs));
mTabs.setOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));

但是你會發現
setOnTabSelectedListener API 24 的時候已經被棄用了
取而代之的是 addOnTabSelectedListener

另外還有一種方法就是當你在點選 Tab 頁面的時候
還會額外再進行一些事情
那麼你就可以透過以下的方式來進行切換

mTabs.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
    @Override
    public void onTabSelected(TabLayout.Tab tab) {
        mViewPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabUnselected(TabLayout.Tab tab) {

    }

    @Override
    public void onTabReselected(TabLayout.Tab tab) {

    }
});

同樣的這個方法也在 API 24 被棄用了
當然還是有替代方案

mTabs.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
    @Override
    public void onTabSelected(TabLayout.Tab tab) {
        mViewPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabUnselected(TabLayout.Tab tab) {

    }

    @Override
    public void onTabReselected(TabLayout.Tab tab) {

    }
});

如此一來就可以很輕鬆的把上下兩個元件的連動綁在一起了