【问题标题】:FragmentStateAdapter not calling createFragment when notifyDataSetChanged is called调用 notifyDataSetChanged 时 FragmentStateAdapter 未调用 createFragment
【发布时间】:2020-10-07 23:43:11
【问题描述】:

我同时使用ViewPager2FragmentStateAdapter

public class MyAdapter extends FragmentStateAdapter {

    public MyAdapter(@NonNull Fragment fragment) {
        super(fragment);
    }

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        return MyFragment.newInstance(MyClass.func(position));
    }

    @Override
    public int getItemCount() {
        return MyClass.NUM;
    }

}

不幸的是,在适配器上调用notifyDataSetChanged() 完全没有效果(调用notifyItemChanged(position) 工作正常)。

我该如何解决这个问题?

【问题讨论】:

    标签: android android-viewpager2 fragmentstateadapter


    【解决方案1】:

    我在 IssueTracker 中为此 here 创建了一个错误报告。但对我来说,即使是 notifyItemChanged(position:)notifyItemRangeChanged(positionStart:itemCount:) 方法的行为也不正确。

    这个错误是由于 FragmentStateAdapter.getItemId(position:) 方法的默认实现,它只返回传递给它的 position。因此,每个positionitemIdFragmentStateAdapter.notifyDataSetChanged() 调用之前和之后都是相同的,因此不会重新创建任何Fragments。

    一种可能的解决方法是在您的FragmentStateAdapter 实现中为每个页面分配一个唯一ID,并在调用notifyDataSetChanged() 方法时为每个页面分配一个新ID。请参阅下面的 ViewPagerAdapter 类中的 init 块,该块有助于解决此问题:AdapterDataObserver 对象已在此 init 块中注册,以便在调用 notifyDataSetChanged() 时接收回调。

    class ViewPagerAdapter(fragmentActivity: FragmentActivity) :
        FragmentStateAdapter(fragmentActivity) {
    
        private var counter = 0L
        private var itemIds: List<Long>
    
        init {
            itemIds = generateListOfItemIds()
    
            val adapterDataObserver = object : AdapterDataObserver() {
    
                override fun onChanged() {
                    itemIds = generateListOfItemIds()
                }
            }
    
            registerAdapterDataObserver(adapterDataObserver)
        }
    
        override fun createFragment(position: Int): Fragment {
            return PageFragment.newInstance(position)
        }
    
        override fun getItemCount(): Int {
            return itemIds.size
        }
    
        override fun getItemId(position: Int): Long {
            return itemIds[position]
        }
    
        override fun containsItem(itemId: Long): Boolean {
            return itemIds.contains(itemId)
        }
    
        private fun generateListOfItemIds() = (1..5).map { counter++ }
    }
    

    【讨论】:

    • 请参阅here 了解演示此ViewPagerAdapter 类的最小Android 应用程序。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-29
    • 1970-01-01
    • 1970-01-01
    • 2014-10-19
    • 1970-01-01
    • 2016-01-20
    • 2020-11-02
    相关资源
    最近更新 更多