我一直在尝试所有建议、解决方案、库等,但它们不是纯循环的,而且大多数时候不支持仅 3 页。
所以我使用新的ViewPager2 实现了一个循环ViewPager 示例,新的ViewPager 使用RecyclerView 和ViewHolders 来处理视图回收并按预期工作!
TLDR: GITHUB
在此示例中,将构建一个带有 ViewPager2 和 FragmentPagerAdapter 的单个活动应用程序,支持 3 个或更多页面之间的循环导航。
我正在使用库 androidx.viewpager2:viewpager2 的 alpha 版本,但 1.0.0-alpha06 是在 google 冻结 API 并转为 beta 之前计划的最后一个版本。
1.将 ViewPager2 库添加到 build.gradle 中的依赖项
dependencies {
implementation 'androidx.viewpager2:viewpager2:1.0.0-alpha06'
}
2。将ViewPager2 视图添加到您的项目中:
<androidx.viewpager2.widget.ViewPager2 xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/vwpHome"
android:layout_width="match_parent"
android:layout_height="match_parent" />
3.创建FragmentStateAdapter 适配器:
getItemCount()需要返回一个huuuuge数字。 (2147483647)
getCenterPage() 根据 huuuuge 号返回中心页面。
该方法用于获取ViewPager2中设置的初始页面位置,此时用户需要滑动~1073741823次才能到达ViewPager2的末尾。
class CircularPagerAdapter(fragmentManager: FragmentManager, lifecycle: Lifecycle) : FragmentStateAdapter(fragmentManager, lifecycle) {
override fun getItemCount() = Integer.MAX_VALUE
/**
* Create the fragment based on the position
*/
override fun createFragment(position: Int) = HomePagerScreens.values()[position % HomePagerScreens.values().size].fragment.java.newInstance()
/**
* Returns the same id for the same Fragment.
*/
override fun getItemId(position: Int): Long = (position % HomePagerScreens.values().size).toLong()
fun getCenterPage(position: Int = 0) = Integer.MAX_VALUE / 2 + position
}
HomeScreens 是一个包含页面信息的 ENUM。
enum class HomePagerScreens(@StringRes val title: Int,
val fragment: KClass<out Fragment>) {
HOME_1(R.string.home_1, FragmentHome::class),
HOME_2(R.string.home_2, FragmentHome::class),
HOME_3(R.string.home_3, FragmentHome::class)
}
4.将适配器设置为 ViewPager
val circularAdapter = CircularPagerAdapter(supportFragmentManager, lifecycle)
vwpHome.apply {
adapter = circularAdapter
setCurrentItem(circularAdapter.getCenterPage(), false)
}