需求
由于 Android 平板控制硬件设备,控制界面要展示的数据太多,一屏装不下。 所以需要新增一个界面,用于展示次要的信息。 交互方式是,在首屏,通过手势滑动,切换到次屏。
找到一个官方的组件 ViewPager2,看上去非常合适。
官方文档只说明了在 Activity 中使用 ViewPager2 的方式,并没有提及是否可以在 Fragment 中使用。 所以需要测试一下。
最终实现效果
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 聊聊, 查看更多联系方式