loop vp adapter

This commit is contained in:
renhaoting 2025-11-18 15:15:32 +08:00
parent b1ab016709
commit 13daa31451
5 changed files with 37 additions and 19 deletions

View File

@ -33,6 +33,7 @@ class HomeFragment : AppViewsFragment<ViewBinding, UiState, ViewModel>(), OnSwit
//private val mViewPagerAdapter by lazy { HomeFragmentStateAdapter(this) }
private val mViewPagerAdapter by lazy { HomeFragmentStateAdapter(this) }
override fun inflateViewBinding(

View File

@ -0,0 +1,28 @@
package com.gamedog.vididin.main.fragments.home
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.adapter.FragmentStateAdapter
class HomeVpLoopAdapter<T>(
private val activity: FragmentActivity,
private val dataList: List<T>,
private val fragmentCreatorFun: (List<T>, Int) -> Fragment
) : FragmentStateAdapter(activity) {
companion object {
private const val LOOP_FRAGMENT_COUNT = 3
}
private val mRealPageCount = LOOP_FRAGMENT_COUNT
override fun getItemCount(): Int = Int.MAX_VALUE
override fun createFragment(position: Int): Fragment {
val fragmentPosition = position % mRealPageCount
return fragmentCreatorFun(dataList, fragmentPosition)
}
}

View File

@ -7,7 +7,7 @@ import androidx.viewpager2.adapter.FragmentStateAdapter
class LoopPagerAdapter<T>(
private val activity: FragmentActivity,
private val dataList: List<T>,
private val fragmentCreatorFun: (List<T>, Int) -> Fragment // 修改点1传入整个数据列表和真实位置, 接收一个创建Fragment的lambda传入数据和在ViewPager中的真实位置
private val fragmentCreatorFun: (List<T>, Int) -> Fragment
) : FragmentStateAdapter(activity) {
private val mRealPageCount = 3

View File

@ -38,16 +38,13 @@ abstract class BaseFragmentStateAdapter<T : BaseFragmentStateDiffItem>(
override fun createFragment(position: Int): Fragment {
return createFragment(position, getItem(position))
// 设置Fragment是否是懒加载初始化
.setFragmentIsLazyInit(isFragmentLazyInit)
}
// 返回对应位置的数据项的唯一ID。
override fun getItemId(position: Int): Long {
return getItem(position).getItemId()
}
// 判断给定的itemId是否在当前数据集中。
override fun containsItem(itemId: Long): Boolean {
return getCurrentList().any { it.getItemId() == itemId }
}
@ -58,7 +55,6 @@ abstract class BaseFragmentStateAdapter<T : BaseFragmentStateDiffItem>(
mDiffer.submitList(list)
}
// 文章https://blog.csdn.net/cxz200367/article/details/115032032
fun getFragmentByIndex(position: Int) =
if (position in 0..<itemCount) fragmentManager.findFragmentByTag("f" + getItemId(position)) else null

View File

@ -8,25 +8,19 @@ import kotlin.collections.isNullOrEmpty
/**
* 设置[list]数据和[createAdapter]创建的Adapter
* [offscreenPageLimit]设置预加载数量null或小于等于0的值为无预加载[Int.MAX_VALUE]为预加载全部其他值为固定预加载数量
* 说明使用此方法是为了解决因为配置变更而导致的页面销毁后的还原ViewPager2原来的位置等问题
* ViewPager2会在setAdapter()的时候进行上次的还原如果以先setAdapter()后再全部通过拿到数据之后再adapter.setData()进行刷新数据则此ViewPager2的还原则会失效
*/
fun <T : BaseFragmentStateDiffItem> ViewPager2.setDataOrAdapter(
list: List<T>?,
dataList: List<T>?,
offscreenPageLimit: Int?,
createAdapter: () -> BaseFragmentStateAdapter<T>,
) {
// 设置预加载
setOffscreenPageLimit(
if (offscreenPageLimit == null || offscreenPageLimit <= 0) {
// 小值,用默认的。
ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT
} else if (offscreenPageLimit == Int.MAX_VALUE) {
// 大值,用全部的。
val itemCount = (list?.size ?: 0)
val itemCount = (dataList?.size ?: 0)
if (itemCount >= 2) {
// 2个及以上
itemCount - 1
@ -41,14 +35,13 @@ fun <T : BaseFragmentStateDiffItem> ViewPager2.setDataOrAdapter(
)
if (adapter == null) {
// create adapter
if (list.isNullOrEmpty()) return // 初始化状态不设置下面的防止没恢复之前保持的数据。不能使用adapter.setStateRestorationPolicy(PREVENT_WHEN_EMPTY)来替代实现因为此ViewPager2是通过setAdapter进行恢复的。
if (dataList.isNullOrEmpty()) return
val fragmentStateAdapter = createAdapter()
fragmentStateAdapter.submitList(list)
// set adapter
fragmentStateAdapter.submitList(dataList)
adapter = fragmentStateAdapter
} else {
// update adapter
adapter.asUnsafe<BaseFragmentStateAdapter<T>>().submitList(list)
adapter.asUnsafe<BaseFragmentStateAdapter<T>>().submitList(dataList)
}
}