首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在RecyclerView.ViewHolder中添加片段

在RecyclerView.ViewHolder中添加片段
EN

Stack Overflow用户
提问于 2017-02-13 21:58:30
回答 4查看 23.4K关注 0票数 18

我有一个RecyclerView.ViewHolder,它会根据传递的对象的实例将不同的片段添加到它的FrameLayout中。问题出现在几乎不可能将片段添加到ViewHolder中的地方。请注意,我已经从父级传递了FragmentManager。最初,我尝试使用以下代码

public void setSomething(boolean A) {
    if (A) {
         mFragmentManager.beginTransaction()
            .replace(mBinding.typeContainerLayout.getId(), new FragmentA())
            .commit();
    } else {
        mFragmentManager.beginTransaction()
            .replace(mBinding.typeContainerLayout.getId(), new FragmentB())
            .commit();
    }
}

这段代码的问题是所有的ViewHolder共享相同的id,因此只有一个ViewHolder可以添加片段。在我的RecyclerView中,只有第一个单元格添加了片段。为了解决这个问题,我创建了另一个FrameLayout并将其添加到typeContainerLayout中。现在我的代码变成这样。

public void setSomething(boolean A) {
    FrameLayout frameLayout = new FrameLayout(mContext);
    frameLayout.setId(View.generateViewId());
    mBinding.typeContainerLayout.removeAllViews();
    mBinding.typeContainerLayout.addView(frameLayout)

    if (A) {
         mFragmentManager.beginTransaction()
            .replace(frameLayout.getId(), new FragmentA())
            .commit();
    } else {
        mFragmentManager.beginTransaction()
            .replace(frameLayout.getId(), new FragmentB())
            .commit();
    }
}

现在,每个ViewHolder都正确地添加了片段,并且有了自己的片段。然而,当我添加了5个ViewHolder并试图向下滚动RecyclerView时,出现了一个运行时错误,它的状态是

java.lang.IllegalArgumentException: No view found for id 0x4 (unknown) for fragment FragmentA{7c55a69 #0 id=0x4 FragmentA}
                      at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1292)
                      at android.support.v4.app.FragmentManagerImpl.moveFragmentsToInvisible(FragmentManager.java:2323)
                      at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2136)
                      at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2092)
                      at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1998)
                      at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:709)
                      at android.os.Handler.handleCallback(Handler.java:739)
                      at android.os.Handler.dispatchMessage(Handler.java:95)
                      at android.os.Looper.loop(Looper.java:148)
                      at android.app.ActivityThread.main(ActivityThread.java:5417)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

我的猜测是,要么id在某个时候冲突了,要么视图由于ViewHolder模式而被破坏了。所以我的问题是。

1)有什么解决方法吗?

2)还有比添加片段更好的做法吗?我添加片段的原因是,ViewHolder的子项的逻辑都可以位于单个片段中。当然,我可以将片段的两个视图都放入ViewHolder xml中。根据条件只使用setVisible()。但这只会让我的ViewHolder包含太多的逻辑。

以防有人对我为什么需要fragment感到困惑。这就是我正在努力实现的目标。The image

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-02-15 07:02:18

简而言之:您不应该在recyclerView中使用片段,这不是它们的目的。

冗长的答案:here

票数 5
EN

Stack Overflow用户

发布于 2019-05-27 18:23:23

您应该确切地知道recyclerview创建了您的持有者,并为他绘制了一个视图,因此您需要在适配器的onViewAttachedToWindow方法中附加一个片段。在你的“附加片段”方法中,你应该检查片段管理器是否已经包含这些片段,以防止创建多个实例。

适配器:

 override fun onViewAttachedToWindow(holder: RecyclerView.ViewHolder) {    
    if(holder is FragmentsHolder){
        attachFragmentToContainer(holder.flContainer)            
    }
    super.onViewAttachedToWindow(holder)
}

方法实现:

 fun attachFragmentToContainer(containerId: Int) {
    val fragment = if (fragmentManager?.fragments?.firstOrNull { it is YourFragment } == null)
        YourFragment.instance()
    else
        null

    if (fragment != null) {
        fragmentManager?.beginTransaction()
            ?.add(containerId, fragment)
            ?.commitNowAllowingStateLoss()
    }
}

这在大量用户上进行了测试-没有崩溃,性能良好。

票数 9
EN

Stack Overflow用户

发布于 2019-09-18 22:32:38

我遇到了同样的问题,并通过在我的onBindViewHolder回调中使用addOnChildAttachStateChangeListener RecyclerView回调解决了它:

listView.addOnChildAttachStateChangeListener(new RecyclerView.OnChildAttachStateChangeListener() {
        @Override
        public void onChildViewAttachedToWindow(@NotNull View view) {
            //Create your fragment container here using the view param and add your fragment to the container
        }

        @Override
        public void onChildViewDetachedFromWindow(@NotNull View view) {
            //Destroy the fragment container here

        }
    });
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42205827

复制
相关文章

相似问题

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