remove fragment in viewPager2 use FragmentStateAdapter, but still display(删除 viewPager2 中的片段使用 FragmentStateAdapter,但仍显示)
问题描述
我有viewPager2和FragmentStateAdapter,还有Fragment1,2,3 4,我在fragment2,想去掉fragment3,在fragment2之后显示fragment4.问题是它总是显示片段3(数据),调试显示片段3已被删除,但显示的页面仍然有片段3内容.
I have a viewPager2 and FragmentStateAdapter, and there are Fragement1, 2,3 4, I am in fragment2, and want to remove fragment3, and display fragment4 after fragment2. The problem is it always show me fragment3(data), the debug shows the fragment3 has been removed, but the displayed page still has fragment3 content.
适配器:
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)
}
推荐答案
最后,它对我有用.当我们调用 notifyDataSetChanged()
时,android 会调用适配器中的 getItemId()
方法,用于检查项目是否已更新.它返回源代码中的位置.这意味着在列表 0..i..n
中,如果您删除 i
,它将变为 0...i...n-1
,i
不会改变,adater 中的数据也不会更新.
Finally, it works for me. when we call notifyDataSetChanged()
, android will call
method getItemId()
in adapter, to check if the item has been updated or not. it returns the position in source code. which means in list 0..i..n
, if you remove i
, it becomes to 0...i...n-1
, the i
won't change and the data won't update in 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)
,
what you need to do is rewrite this method and containsItem(long)
,
就我而言,我使用每个片段的哈希码:
for my case, I use the hashcode of each fragment:
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)
}
}
这篇关于删除 viewPager2 中的片段使用 FragmentStateAdapter,但仍显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:删除 viewPager2 中的片段使用 FragmentStateAdapter,但仍显示
基础教程推荐
- Android:对话框关闭而不调用关闭 2022-01-01
- 如何在 UIImageView 中异步加载图像? 2022-01-01
- 在 gmail 中为 ios 应用程序检索朋友的朋友 2022-01-01
- 当从同一个组件调用时,两个 IBAction 触发的顺序是什么? 2022-01-01
- android 应用程序已发布,但在 google play 中找不到 2022-01-01
- UIWebView 委托方法 shouldStartLoadWithRequest:在 WKWebView 中等效? 2022-01-01
- 如何在 iPhone 上显示来自 API 的 HTML 文本? 2022-01-01
- 如何让对象对 Cocos2D 中的触摸做出反应? 2022-01-01
- 如何在没有IB的情况下将2个按钮添加到右侧的UINavigationbar? 2022-01-01
- Kivy Buildozer 无法构建 apk,命令失败:./distribute.sh -m “kivy"d 2022-01-01