ViewPager2 的 FragmentStateAdapter notifyItemChanged 未按预期工作

Kar*_*han 6 android android-viewpager2

我正在使用带有 FragmentStateAdapter 的 ViewPager2,我正在调用 notifyItemChanged(position)。但正如预期的那样 createFragment 方法不会再次调用。这是预期的行为还是错误,我该怎么办

我的代码是

    class EEditionPagerAdapter(
    fragmentManager: FragmentManager, lifecycle: Lifecycle, private var date: String
    ) : FragmentStateAdapter(fragmentManager, lifecycle) {

    private var menuList = emptyList<EEditionMenu>()

    override fun getItemCount(): Int = menuList.size

    override fun createFragment(position: Int): Fragment {
        val menu = menuList[position]
        return EEditionListingFragment.newInstance(menu, date)
    }

    fun submitList(list: List<EEditionMenu>) {
        menuList = list
        notifyItemRangeChanged(0, menuList.size)
    }

    fun changeDate(date: String, position: Int){
        this.date = date
        notifyItemChanged(position)
    }
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*oft 5

FragmentStateAdapter 使用项目 ID 来确定片段是否已创建并重用已创建的片段。默认情况下,项目 ID 是项目的位置。您可以根据位置和日期覆盖getItemIdcontainsItem提供自己的唯一 ID,然后在日期更改时它会要求提供新片段。


kal*_*912 4

当您为 FragmentStateAdapter 调用 notificationItemChanged 时,它会调用ensureFragment(position)恢复片段(如果已经创建)

 private void ensureFragment(int position) {
    long itemId = getItemId(position);
    if (!mFragments.containsKey(itemId)) {
        // TODO(133419201): check if a Fragment provided here is a new Fragment
        Fragment newFragment = createFragment(position);
        newFragment.setInitialSavedState(mSavedStates.get(itemId));
        mFragments.put(itemId, newFragment);
    }
}
Run Code Online (Sandbox Code Playgroud)

尝试重写 onBindViewHolder 并将 Date 设置为片段

   override fun onBindViewHolder(
    holder: FragmentViewHolder,
    position: Int,
    payloads: MutableList<Any>
) {
    super.onBindViewHolder(holder, position, payloads)
    val fragment: EEditionListingFragment? = fragmentManager.findFragmentByTag("f$position") as EEditionListingFragment?
    fragment.updateDate(date)
}
Run Code Online (Sandbox Code Playgroud)