Android自带的TabLayout实现滑动翻页效果(实例)

·  阅读 1332

Android自带的TabLayout在support包中,导包:

implementation 'com.android.support:support-v4:27.1.1'
复制代码

效果1

不带viewpager,tab只可点击,就是普通的控件。

TabLayout嵌套TabItem,可改造空间有限。tabLayout只能嵌套TabItem,其余会报错。

<android.support.design.widget.TabLayout
        android:id="@+id/tabLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#e1e1e1"
        app:tabSelectedTextColor="@color/colorAccent"
        app:tabTextColor="@color/black"
        app:tabIndicatorColor="@color/colorAccent"
        app:tabMode="fixed"
        app:tabIndicatorHeight="4dp">

        <android.support.design.widget.TabItem
            android:id="@+id/tab1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/tab1"/>

        <android.support.design.widget.TabItem
            android:id="@+id/tab2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/tab2"/>

        <android.support.design.widget.TabItem
            android:id="@+id/tab3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/tab3"/>

    </android.support.design.widget.TabLayout>
复制代码

效果2

fragment + viewpager + tabLayout

虽然看着没多大区别,但里面是嵌套了3个Fragment,可以左右切换。

tabLayout.setupWithViewPager(viewPager) 执行这句之后,tabLayout布局嵌套的tabItem会失效,展示的每个tab是通过FragmentPagerAdapter的getPageTitle来获取的。等会儿可以源码解释下。

xml布局:就是简单的tabLayout和viewPager嵌套在一个垂直的linearLayout中

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".tablayout.TabLayoutActivity">

    <android.support.design.widget.TabLayout
        android:id="@+id/tabLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#e1e1e1"
        app:tabSelectedTextColor="@color/colorAccent"
        app:tabTextColor="@color/black"
        app:tabIndicatorColor="@color/colorAccent"
        app:tabMode="fixed"
        app:tabIndicatorHeight="4dp"/>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>
复制代码

kotlin代码

class TabLayoutActivity : AppCompatActivity() {

    var mFragmentList = arrayListOf<Fragment>()
    val mTabTitle = listOf("英语", "数学", "语文")
    var mAdapter: FragmentPagerAdapter? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_tab_layout)
        initTabLayout()
    }

    private fun initTabLayout() {
        mFragmentList.add(FragmentOne())
        mFragmentList.add(FragmentTwo())
        mFragmentList.add(FragmentThree()) 

        mAdapter = FragmentPagerAdapterNew(supportFragmentManager, mFragmentList, mTabTitle)
        viewPager.adapter = mAdapter //设置viewPager的adapter
        tabLayout.setupWithViewPager(viewPager) //建立tabLayout和ViewPager的联系
    }

    class FragmentPagerAdapterNew(val fragementManager: FragmentManager,
                                  val mFragmentList: List<Fragment>,
                                  val mTabTitle: List<String>)
        : FragmentPagerAdapter(fragementManager) {
        override fun getItem(position: Int): Fragment {
            return mFragmentList[position] //切换tab展示的fragment
        }

        override fun getCount(): Int {
            return mFragmentList.size //总共有多少个tab/fragment
        }

        override fun getPageTitle(position: Int): CharSequence? {
            return mTabTitle[position] //展示tab的标题
        }
    }
}
复制代码

效果3

tab展示文字+图片的效果自行百度吧,因为我不打算用这个控件在项目中,用一个开源的更简单的FlycoTabLayout,下一篇就讲这个开源控件。

setViewPagerAdapter(viewPager)

现在解释下setViewPagerAdapter(viewPager)之后,tabLayout中的tabItem失效

首先removeAllTabs,然后根据mPagerAdapter.getCount得到tab个数,然后一个个通过addTab添加进行,newTab().setText(mPagerAdapter.getPageTitle(i)) tab设置的text就是我们刚刚说的, FragmentPagerAdapter里getPagerTitle()返回的啦

省略大部分代码

    public void setupWithViewPager(@Nullable ViewPager viewPager) {
        setupWithViewPager(viewPager, true);
    }

    public void setupWithViewPager(@Nullable final ViewPager viewPager, boolean autoRefresh) {
        setupWithViewPager(viewPager, autoRefresh, false);
    }

    private void setupWithViewPager(@Nullable final ViewPager viewPager, boolean autoRefresh,
            boolean implicitSetup) {
            final PagerAdapter adapter = viewPager.getAdapter();
            if (adapter != null) {
                setPagerAdapter(adapter, autoRefresh);
            }
    }
    
    void setPagerAdapter(@Nullable final PagerAdapter adapter, final boolean addObserver) {
        // Finally make sure we reflect the new adapter
        populateFromPagerAdapter();
    }
    
    void populateFromPagerAdapter() {
        removeAllTabs();  //就是这里啦,首先removeAllTabs

        if (mPagerAdapter != null) {
            final int adapterCount = mPagerAdapter.getCount();
            for (int i = 0; i < adapterCount; i++) {
                addTab(newTab().setText(mPagerAdapter.getPageTitle(i)), false);
            }

            // Make sure we reflect the currently set ViewPager item
            if (mViewPager != null && adapterCount > 0) {
                final int curItem = mViewPager.getCurrentItem();
                if (curItem != getSelectedTabPosition() && curItem < getTabCount()) {
                    selectTab(getTabAt(curItem));
                }
            }
        }
    }
复制代码