【发布时间】:2017-07-01 13:02:06
【问题描述】:
我有一个 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 包含太多逻辑。
如果有人对我为什么需要片段感到困惑。这就是我想要达到的目标。 The image
【问题讨论】:
-
你不要在 recyclerview 中使用片段。您可能需要使用ViewPager
-
为了解决这个问题,您可以在视图持有者中添加一个 FrameLayout 以获得一个 Id。通常,我们通过扩展 RecyclerView.Adapter
来使用适配器 -
我有一个项目清单。根据对象的实例,项目的 ViewHolder 的底部是不同的。这就是我使用片段的原因。它们都共享相同的顶部。
-
不要使用
FragmentManager:在项目布局xml中添加你的片段 -
我遇到了同样的问题。我解决了它。只需为您的容器布局设置新的唯一 ID,您就可以将任何片段添加到您的 recyclerview 项目。这个答案对我有帮助。 stackoverflow.com/a/42994810/1931613。例如,myContainerLayout.setId(SystemClock.currentThreadTimeMillis().toInt())
标签: android android-fragments android-viewholder