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) } private val mViewPagerAdapter by lazy { HomeFragmentStateAdapter(this) }
override fun inflateViewBinding( 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>( class LoopPagerAdapter<T>(
private val activity: FragmentActivity, private val activity: FragmentActivity,
private val dataList: List<T>, 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) { ) : FragmentStateAdapter(activity) {
private val mRealPageCount = 3 private val mRealPageCount = 3

View File

@ -38,16 +38,13 @@ abstract class BaseFragmentStateAdapter<T : BaseFragmentStateDiffItem>(
override fun createFragment(position: Int): Fragment { override fun createFragment(position: Int): Fragment {
return createFragment(position, getItem(position)) return createFragment(position, getItem(position))
// 设置Fragment是否是懒加载初始化
.setFragmentIsLazyInit(isFragmentLazyInit) .setFragmentIsLazyInit(isFragmentLazyInit)
} }
// 返回对应位置的数据项的唯一ID。
override fun getItemId(position: Int): Long { override fun getItemId(position: Int): Long {
return getItem(position).getItemId() return getItem(position).getItemId()
} }
// 判断给定的itemId是否在当前数据集中。
override fun containsItem(itemId: Long): Boolean { override fun containsItem(itemId: Long): Boolean {
return getCurrentList().any { it.getItemId() == itemId } return getCurrentList().any { it.getItemId() == itemId }
} }
@ -58,7 +55,6 @@ abstract class BaseFragmentStateAdapter<T : BaseFragmentStateDiffItem>(
mDiffer.submitList(list) mDiffer.submitList(list)
} }
// 文章https://blog.csdn.net/cxz200367/article/details/115032032
fun getFragmentByIndex(position: Int) = fun getFragmentByIndex(position: Int) =
if (position in 0..<itemCount) fragmentManager.findFragmentByTag("f" + getItemId(position)) else null 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( fun <T : BaseFragmentStateDiffItem> ViewPager2.setDataOrAdapter(
list: List<T>?, dataList: List<T>?,
offscreenPageLimit: Int?, offscreenPageLimit: Int?,
createAdapter: () -> BaseFragmentStateAdapter<T>, createAdapter: () -> BaseFragmentStateAdapter<T>,
) { ) {
// 设置预加载
setOffscreenPageLimit( setOffscreenPageLimit(
if (offscreenPageLimit == null || offscreenPageLimit <= 0) { if (offscreenPageLimit == null || offscreenPageLimit <= 0) {
// 小值,用默认的。 // 小值,用默认的。
ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT
} else if (offscreenPageLimit == Int.MAX_VALUE) { } else if (offscreenPageLimit == Int.MAX_VALUE) {
// 大值,用全部的。 // 大值,用全部的。
val itemCount = (list?.size ?: 0) val itemCount = (dataList?.size ?: 0)
if (itemCount >= 2) { if (itemCount >= 2) {
// 2个及以上 // 2个及以上
itemCount - 1 itemCount - 1
@ -41,14 +35,13 @@ fun <T : BaseFragmentStateDiffItem> ViewPager2.setDataOrAdapter(
) )
if (adapter == null) { if (adapter == null) {
// create adapter if (dataList.isNullOrEmpty()) return
if (list.isNullOrEmpty()) return // 初始化状态不设置下面的防止没恢复之前保持的数据。不能使用adapter.setStateRestorationPolicy(PREVENT_WHEN_EMPTY)来替代实现因为此ViewPager2是通过setAdapter进行恢复的。
val fragmentStateAdapter = createAdapter() val fragmentStateAdapter = createAdapter()
fragmentStateAdapter.submitList(list) fragmentStateAdapter.submitList(dataList)
// set adapter
adapter = fragmentStateAdapter adapter = fragmentStateAdapter
} else { } else {
// update adapter // update adapter
adapter.asUnsafe<BaseFragmentStateAdapter<T>>().submitList(list) adapter.asUnsafe<BaseFragmentStateAdapter<T>>().submitList(dataList)
} }
} }