删除 viewPager2 中的片段使用 FragmentStateAdapter,但仍显示
Posted
技术标签:
【中文标题】删除 viewPager2 中的片段使用 FragmentStateAdapter,但仍显示【英文标题】:remove fragment in viewPager2 use FragmentStateAdapter, but still display 【发布时间】:2020-01-16 05:35:51 【问题描述】:我有viewPager2和FragmentStateAdapter,还有Fragment1,2,3 4,我在fragment2,想去掉fragment3,在fragment2之后显示fragment4。 问题是它总是显示片段3(数据),调试显示片段3已被删除,但显示的页面仍然有片段3内容。
适配器:
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)
【问题讨论】:
我有 2 个片段 mainfragment 和 otherfragment 。我在每 5 个位置之后添加 otherfragment 并且它不在 arraylist 中,那么如果它不在 list 中,如何删除该 otherfragment ?我正在使用 viewpager2 【参考方案1】:最后,它对我有用。当我们调用notifyDataSetChanged()
时,android会调用
适配器中的方法getItemId()
,用于检查项目是否已更新。它返回源代码中的位置。这意味着在0..i..n
列表中,如果你删除i
,它变成0...i...n-1
,i
不会改变,数据也不会在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)
【讨论】:
请找到更多有用的信息:***.com/questions/7263291/… 哇,你太棒了!你拯救了这一天:) 干杯 @Xianwei 这是 API 的一个完全不同的部分,不幸的是不相关 我花了几个小时试图解决这个问题。 Android 的不幸之处在于,它并不总是直观的,而且关于这些用例的文档也不完整。 对我来说每次更新号码也需要重新初始化pageIds = items.map it.hashCode().toLong()
以上是关于删除 viewPager2 中的片段使用 FragmentStateAdapter,但仍显示的主要内容,如果未能解决你的问题,请参考以下文章