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

更新日期: 2023-07-21 阅读次数: 793 字数: 810 分类: Android

需求

由于 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 聊聊, 查看更多联系方式