remove fragment in viewPager2 use FragmentStateAdapter, but still display

后端 未结 1 2035
無奈伤痛
無奈伤痛 2021-02-01 06:27

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 proble

相关标签:
1条回答
  • 2021-02-01 06:52

    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;
    }
    

    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)
    }
    }
    
    0 讨论(0)
提交回复
热议问题