remove fragment in viewPager2 use FragmentStateAdapter, but still display remove fragment in viewPager2 use FragmentStateAdapter, but still display android android

remove fragment in viewPager2 use FragmentStateAdapter, but still display


Finally, it works for me. when we call notifyDataSetChanged(), android will callmethod 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()} */@Overridepublic long getItemId(int position) {    return position;}

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.fragmentFactoryprivate val classLoader = context.classLoaderprivate val pageIds= items.map { it.hashCode().toLong() }override fun getItemCount(): Int = items.sizeoverride 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.simpleNamefun 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)}}