3

我正在使用 aViewPager2和 a FragmentStateAdapter

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)工作正常)。

我该如何解决这个问题?

4

1 回答 1

4

我在 IssueTracker中为此创建了一个错误报告。不过,对我来说,甚至notifyItemChanged(position:)andnotifyItemRangeChanged(positionStart:itemCount:)方法的行为也不正确。

该错误是由于该FragmentStateAdapter.getItemId(position:)方法的默认实现仅返回position传递给它的方法。因此,itemIdfor each在调用position之前和之后将是相同的,因此不会重新创建任何 s。FragmentStateAdapter.notifyDataSetChanged()Fragment

一种可能的解决方法是在您的实现中为每个页面分配一个唯一的 id,并在调用该方法FragmentStateAdapter时为每个页面分配一个新的 id 。notifyDataSetChanged()请参阅下面类中的init块,该块ViewPagerAdapter有助于解决此问题: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++ }
}
于 2020-10-16T17:54:37.063 回答