Android 使用 ViewPager2 实现手势侧滑翻页

文章目录

    需求

    由于 Android 平板控制硬件设备,控制界面要展示的数据太多,一屏装不下。
    所以需要新增一个界面,用于展示次要的信息。
    交互方式是,在首屏,通过手势滑动,切换到次屏。

    找到一个官方的组件 ViewPager2,看上去非常合适。

    官方文档只说明了在 Activity 中使用 ViewPager2 的方式,并没有提及是否可以在 Fragment 中使用。
    所以需要测试一下。

    最终实现效果

    Android ViewPager2 实现侧滑翻页

    ViewPager2

    ViewPager2 是 Android Jetpack 中的一个库,它提供了一种以滑动方式浏览多个页面的方式。支持垂直和水平方向的滑动,并且具有更好的性能和更灵活的 API。

    主要用途包括:

    • 展示多个页面:例如图片、文本、视频等等。例如,抖音 APP 无限下滑刷视频,就是一个典型的应用场景。
    • 实现引导页:用户可以通过滑动浏览不同的页面。
    • 实现轮播图:例如展示广告、推荐内容等等。
    • 实现横向列表:例如展示商品列表、新闻列表等等。

    Fragment 中使用 ViewPager2

    Google 官方示例用的是 Activity 作为宿主。这里说可以用 Fragment 作为宿主:

    https://stackoverflow.com/questions/60957775/howto-nest-viewpager2-within-a-fragment

    代码结构

    核心是 ViewPager2 放在那里。

    放在 MainActivity 里不现实,因为里面有 navigation 相关的。

    其实就是平替掉 HomeFragment, 换成一个 ViewPagerWrapper 作为默认的 Fragment.

    • ViewPagerWrapper 中包含 HomeFragment 和 DataFragment
    • 其他 Fragment 与 ViewPagerWrapper 平级
    • 原来跳转 HomeFragment 的逻辑都需要改成跳转 ViewPagerWrapper,然后传递参数给 HomeFragment

    新建一个 ViewPager Wrapper Fragment

    例如名为 ViewPagerWrapperFragment.

    layout XML 内容为:

    <?xml version="1.0" encoding="utf-8"?>
    
    <androidx.viewpager2.widget.ViewPager2 xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    

    Fragment 中的 Kotlin 代码:

    onCreateView 中:

    val adapter = ScreenSlidePagerAdapter(this)
    binding.pager.adapter = adapter
    

    定义一个 FragmentStateAdapter 在 Fragment 中:

    private inner class ScreenSlidePagerAdapter(fa: ViewPagerWrapperFragment) :
    	FragmentStateAdapter(fa) {
    	override fun getItemCount(): Int = 2
    
    	override fun createFragment(position: Int): Fragment {
    		return when (position) {
    			0 -> HomeFragment()
    			1 -> DataFragment()
    			else -> throw IllegalStateException("Unexpected position: $position")
    		}
    	}
    }
    

    编译并真机测试了一下,确实可以使用。

    哈哈,太顺利了。实际上,逻辑部分 Google 官方文档写的不全,最终靠 ChatGPT 解决。

    参数传递

    需要将其他页面跳转 ViewPager Wrapper 页的参数,传递给 HomeFragment (View Pager 的子页面)。

    只需要将 HomeFragment 中的参数解析逻辑,迁移到 ViewPagerWrapper 中即可,非常简单。

    底部切换标识

    切换 tab 标识还是需要加的,否则用户很难知道还有次级页面。

    可以使用这个三方库,用来作为 ViewPager2 的 Dot Indicator

    https://github.com/tommybuonomo/dotsindicator

    这个库同时支持 XML 和 Jetpack Compose.

    参考里面的配置就行。

    只有一个地方需要注意,由于我的界面完全是在子 fragment 中实现的,所以这个组件方法子 fragment 的 layout 文件中,
    那么与宿主 fragment 中的 view pager 组件绑定就需要通过:

    binding.wormDotsIndicator.attachTo((requireParentFragment() as ViewPagerWrapperFragment).binding.pager)
    

    参考

    • https://developer.android.com/develop/ui/views/animations/screen-slide-2
    • https://www.geeksforgeeks.org/viewpager2-in-android-with-example/
    • https://stackoverflow.com/questions/72503410/how-can-i-create-all-the-fragments-of-viewpager2-when-the-app-runs
    • https://stackoverflow.com/questions/60957775/howto-nest-viewpager2-within-a-fragment

    关于作者 🌱

    我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式