首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >FragmentStateAdapter for ViewPager2 notifyItemChanged未按预期工作

FragmentStateAdapter for ViewPager2 notifyItemChanged未按预期工作
EN

Stack Overflow用户
提问于 2020-02-26 06:49:19
回答 3查看 5.3K关注 0票数 7

我将ViewPager2与FragmentStateAdapter结合使用,并调用notifyItemChanged(position)。但正如预期的那样,createFragment方法不会再次调用。是故意的行为还是错误,我该怎么做?

我的密码是

代码语言:javascript
运行
复制
    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)
    }
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-02-26 07:28:37

当您调用notifyItemChanged for FragmentStateAdapter时,它调用ensureFragment(position),如果片段已经创建,它就会恢复它。

代码语言:javascript
运行
复制
 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);
    }
}

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

代码语言:javascript
运行
复制
   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)
}
票数 4
EN

Stack Overflow用户

发布于 2020-07-16 23:22:03

FragmentStateAdapter使用项ID来确定是否已经创建了一个片段,并且重用了已经创建的片段。默认情况下,项ID是项的位置。您可以重写getItemIdcontainsItem,根据位置和日期提供您自己的唯一ID,然后当日期更改时,它将请求一个新的片段。

票数 6
EN

Stack Overflow用户

发布于 2020-04-14 19:40:17

在mFragment中放置到FragementStateAdapter.class中的片段由

代码语言:javascript
运行
复制
void placeFragmentInViewHolder(@NonNull final FragmentViewHolder holder)

方法,它是包私有的,我们没有访问权限,在这个方法中,片段被添加到mFragment管理器中,标记"f" + holder.getItemId()"f" + position相同。

代码语言:javascript
运行
复制
        scheduleViewAttach(fragment, container);
        mFragmentManager.beginTransaction()
                .add(fragment, "f" + holder.getItemId())
                .setMaxLifecycle(fragment, STARTED)
                .commitNow();
        mFragmentMaxLifecycleEnforcer.updateFragmentMaxLifecycle(false);

因此,我们可以在显示碎片时重写onBindViewHolder方法。

代码语言:javascript
运行
复制
@Override
public void onBindViewHolder(@NonNull FragmentViewHolder holder, int position, @NonNull List<Object> payloads) {
    super.onBindViewHolder(holder, position, payloads);
    if (position == 0) {

        String fragmentTag = "f" + holder.getItemId();
        Log.v(TAG,"fragmentTag is : " + fragmentTag);
        MyFragment fragment0 = (MyFragment) this.mFragmentManger.findFragmentByTag(fragmentTag);

        if (fragment0 != null) {
            Log.v(TAG,"onBindViewHolder updating fragment ...");
            // do what ever you want to update the MyFragment 
            fragment0.update(payloads);
        } else {
            Log.v(TAG,"onBindViewHolder called, but fragment0 is null!");
        }
    }
} 

在我的例子中,this.mFragmentManager是通过构造函数兑现的。

代码语言:javascript
运行
复制
public MyFragmentStateAdapter(@NonNull Fragment fragment) {
        super(fragment); // this calls the fragment.getChildFragmentManager().
        this.mFragmentManger = fragment.getChildFragmentManager();
}

createFragment()是:

代码语言:javascript
运行
复制
@NonNull
@Override
public Fragment createFragment(int position) {
    if(position == 0){
        if (this.fragment0 == null) {
            this.fragment0 = MyFragment.getInstance();
        }
        return this.fragment0;
    } else {
        Log.v(TAG, "position " + position + " is called");
        return null;
    }
}

最后,调用其他地方的更新以触发更新:

代码语言:javascript
运行
复制
ViewPager2.getAdapter().notifyItemChanged(0, null); 
// 0 is the fragment position of the fragment0 and null is payload.
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60408236

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档