FragmentStateAdapter在notifyDataSetChanged后没有重新创建currentFragment

19

我有一个 FragmentStateAdapter 作为 ViewPager2 的适配器。

class DefaultFragmentStateAdapter(fragment: Fragment) : FragmentStateAdapter(fragment) {

    var items = listOf<Fragment>()
       set(value) {
           field = value
           notifyDateSetChanged()
       }

    override fun getItemCount(): Int = items.size

    override fun createFragment(position: Int): Fragment = items[position]
}
适配器的项目可能会根据用户选择的日期而改变,因此需要进行动态处理。 问题在于,在我调用adapter.items = {new_fragments}之后,当前的片段没有重新加载,只有当我转到ViewPager中的最后一页并返回第一页时,才能看到更新的片段。 当前片段在调用notifyDataSetChanged时不会更新。
我该如何管理以更新当前显示的片段?
2个回答

25

我不得不重写以下两个方法...

override fun getItemId(position: Int): Long {
    return items[position].id
}

override fun containsItem(itemId: Long): Boolean = items.any { it.id == itemId }

...让它工作起来!


返回项[position].id需要一个长整型值。 - Abraham Mathew
我不知道为什么重写getItemId()和containsItem()会导致片段加载两次。 - Taha
我也需要理解为什么。 - Keith Mak
这是解决Viewpager2奇怪行为的真正方法。在我的情况下,由于我的数据中没有可用的ID,我创建了虚假的ID,并在每次更新数据时更新这些ID。 - Miguel Sesma
如果您想将属性用作ID,可以执行以下操作:items.get(position).getId().hashCode().toLong() - Gilberto Ibarra

-1

我发现最好的方法是setUserVisibleHint

将此代码添加到您的片段中

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser) {
        // load data here
    }else{
       // fragment is no longer visible
    }
}

根据文档,页面限制必须大于1,否则会抛出异常! - Manuel Munoz
抱歉,当我使用5时它是有效的,这里是更新。 - Jamaldin Sabirjanov
3
@JamaldinSabirjanov,我不清楚为什么覆盖Fragment的setUserVisibleHint(isVisibleToUser:)方法会解决FragmentStateAdapter中的问题。但出于好奇,我确实覆盖了它,并观察到在FragmentStateAdapter.notifyDataSetChanged()调用之前或之后都没有被调用。请解释一下为什么或如何解决这个问题。我还注意到,在尝试使用这个标记为弃用的方法时,发现了一些问题。请参见此处 - Adil Hussain

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接