在一个页面下分多个 tab,可以用 ViewPager + TabLayout 来实现。ViewPager 用来切换 tab 页面,TabLayout 用来展示 tab 栏。
官方文档对这两者结合起来的用法也有指导推荐,
布局
这样布局是带有从属关系的,TabLayout 与 ViewPager 自动关联,滑动 ViewPager 切换页面时,相应 tab 栏也会跟着切换,同样的,切换 tab 栏时 ViewPager 页面也会跟着切换。
当然也可以不这样,而是像两个普通控件一样摆放,
如果这样摆放的话,因为 ViewPager 和 TabLayout 没有了从属关系,也就不会自动关联。这样的话,只能通过代码建立关联,
//像这样就可以在代码里建立两者的关联。
tabLayout.setupWithViewPager(viewPager);
所以,要想 ViewPager 和 TabLayout 建立关联,上面两者方式二选一即可(这是我通过代码编译实测的)
ViewPager 适配器
写好布局之后,就要为 ViewPager 设置适配器了,系统为 ViewPager 提供了 PagerAdapter,因为是抽象类,所以如果要用,需要用子类继承自 PagerAdapter 来实现。但考虑到用 ViewPager 的场景一般用 Fragment 的比较多,所以系统又提供了两个和 Fragment 相关的适配器,
FragmentPagerAdapter
可用于页面数量较少,或者页面固定不会动态增加减少的情况FragmentStatePagerAdapter
用于页面数量较多的情况,适配器会根据情况对不展示的 Fragment 页面进行销毁以减少内存的使用,达到优化内存的目的。
拿 FragmentPagerAdapter 来说,需要实现的方法有 getCount() 和 getItem(),前者表示页面的数量,后者会根据入参来返回具体页面的 Fragment 对象。
当然,如果 ViewPager 关联了 TabLayout,那么还要实现 getPageTitle() 方法,该方法会根据入参来返回具体页面对应的 tab 名字。也就是说,只要 ViewPager 和 TabLayout 做了关联,TabLayout 就不需要单独再添加 Tab 了(即使通过 addTab 方法加了也没用),而是通过 getPageTitle() 返回对应 tab 的名称,至于 tab 的个数自然和页面数量是一致的。
到这步,页面展示滑动什么的都没问题了,接下去的重点就是具体 Fragment 与业务逻辑的实现了。可见,用这样的方式实现分页效果,我们可以集中精力做我们关心的事情上。