android - 在 RecyclerView.ViewHolder 中添加 fragment

标签 android android-fragments android-viewholder

我有一个 RecyclerView.ViewHolder,它将根据传递的对象实例将不同的 fragment 添加到其 FrameLayout 中。问题出在几乎不可能将 fragment 添加到 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 可以添加 fragment 。在我的 RecyclerView 中,只有第一个单元格添加了 fragment 。为了解决这个问题,我创建了另一个 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 都正确添加了 fragment 并拥有了自己的 fragment。然而,当我添加 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 在某些时候发生冲突,或者 View 由于 ViewHolder 模式而被破坏。所以我的问题是。

1) 有什么解决方法吗?

2)有没有比添加 fragment 更好的做法。我添加 fragment 的原因是 ViewHolder 的子项的逻辑都可以位于单个 fragment 中。当然,我可以将 fragment 的两个 View 都放入 ViewHolder xml 中。并且只是 setVisible() 取决于条件。但这只会让我的 ViewHolder 包含太多逻辑。

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

最佳答案

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

适配器:

 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()
    }
}

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

关于android - 在 RecyclerView.ViewHolder 中添加 fragment ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42205827/

相关文章:

java - 未输入 ViewHolder 中的 OnClickListener

android - 如何打开相机,或从 recycleriew 项目中的按钮调用 startActivityForResult

android - FragmentStatePagerAdapter.getItem() 返回错误的位置

android - 如何从 sqlite 游标中获取列值?

Android fragment 在堆栈中移动

android - DialogFragment 在方向更改时使应用程序崩溃

android - 使用不同布局时的 Listview 回收

Android向viewpager添加了圆形指示器

android - 如何限制 android 中相机的预览 fps 范围?

android - 如何在Fragment中使用SupportMapFragment?