android 使用FragmentStateAdapter删除viewPager2中的片段,但仍显示

p1tboqfb  于 2023-01-07  发布在  Android
关注(0)|答案(2)|浏览(306)

我有viewPager2和FragmentStateAdapter,有Fragment1、2、3和4,我在fragment2中,想删除fragment3,在fragment2之后显示fragment4,问题是它总是显示fragment3(数据),调试显示fragment3已删除,但显示的页面仍有fragment3内容。
适配器:

class TipsAdapter(
private val items: MutableList<TripPage>,
context: FragmentActivity
) : FragmentStateAdapter(context) {

private val fragmentFactory = context.supportFragmentManager.fragmentFactory
private val classLoader = context.classLoader

override fun getItemCount(): Int = items.size

override fun createFragment(position: Int): Fragment {
    val pageInfo = items[position]
    val fragment = fragmentFactory.instantiate(classLoader, pageInfo.fragmentClass.name)
    fragment.arguments = Bundle().also { it.putParcelable(PAGE_INFO, pageInfo) }
    return fragment
}

fun getFragmentName(position: Int) = items[position].fragmentClass.simpleName

fun removeFragment(position: Int) {
    items.removeAt(position)
    notifyItemRemoved(position)
    notifyItemRangeChanged(position, items.size)
    notifyDataSetChanged()
}

}
删除片段代码:

if ((view_pager.adapter as TipsAdapter).getFragmentName(index + 1).equals(
            TripPreFragment::class.simpleName) &&
            viewModel.shouldRemoveBulkApply()) {
            (view_pager.adapter as TipsAdapter).removeFragment(index + 1)
            view_pager.setCurrentItem(index + 1, true)
        } else {
            view_pager.setCurrentItem(index + 1, true)
        }
rta7y2nd

rta7y2nd1#

最后,它为我工作.当我们调用notifyDataSetChanged(),android将调用方法getItemId()在适配器,检查是否已更新或没有.它返回的位置在源代码.这意味着在列表0..i..n,如果你删除i,它变成0...i...n-1i不会改变,数据不会在adater更新.

/**
 * Default implementation works for collections that don't add, move, remove items.
 * <p>
 * TODO(b/122670460): add lint rule
 * When overriding, also override {@link #containsItem(long)}.
 * <p>
 * If the item is not a part of the collection, return {@link RecyclerView#NO_ID}.
 *
 * @param position Adapter position
 * @return stable item id {@link RecyclerView.Adapter#hasStableIds()}
 */
@Override
public long getItemId(int position) {
    return position;
}

你需要做的就是重写这个方法和containsItem(long)
对于我的例子,我使用每个片段的散列码:

class TipsAdapter(
     private val items: MutableList<TripPreferencesOptimizerPage>,
     context: FragmentActivity
    ) : FragmentStateAdapter(context) {

private val fragmentFactory = context.supportFragmentManager.fragmentFactory
private val classLoader = context.classLoader
private val pageIds= items.map { it.hashCode().toLong() }

override fun getItemCount(): Int = items.size

override fun createFragment(position: Int): Fragment {
    val pageInfo = items[position]
    val fragment = fragmentFactory.instantiate(classLoader, pageInfo.fragmentClass.name)
    fragment.arguments = Bundle().also { it.putParcelable(PAGE_INFO, pageInfo) }
    return fragment
}

fun getFragmentName(position: Int) = items[position].fragmentClass.simpleName

fun removeFragment(position: Int) {
    items.removeAt(position)
    notifyItemRangeChanged(position, items.size)
    notifyDataSetChanged()
}

override fun getItemId(position: Int): Long {
    return items[position].hashCode().toLong() // make sure notifyDataSetChanged() works
}

override fun containsItem(itemId: Long): Boolean {
    return pageIds.contains(itemId)
}
}
vbkedwbf

vbkedwbf2#

最简单的解决方案如下。

items.removeAt(position)
notifyDataSetChanged()

然后从您的Activity或片段调用此函数

view_pager.setCurrentItem(index - 1, true)

这将删除你的碎片和动画一样删除项目在recyclerview如果你正在查看删除碎片。

相关问题