在我的例子中,我有一个适配器,它与一个recyclerView一起工作,传递给适配器的项是具有自己视图的项。
所需要的只是一个线性布局作为每个项目传递的容器,所以我所做的是在onBindViewHolder内的指定位置抓取项目,然后将其添加到线性布局,然后显示。
在文档中检查基础知识,
当一个项目滚动出屏幕时,RecyclerView不会销毁它
视图
因此,与我的项目,当我滚动到一个方向,然后改变到相反的方向-快速,最近显示的项目还没有被销毁,这意味着,项目仍然与线性布局容器相关联,然后在我的端,我试图附加到另一个容器,这最终与一个孩子已经有一个父母。
我的解决方案是检查指定的项是否有父项,如果有,我将其分配给一个变量,然后调用parentVar.removeView(item),然后分配新的父项。
以下是示例代码(有问题的适配器):
override fun onBindViewHolder(holder: QuestionWidgetViewHolder, position: Int) {
holder.linearLayoutContainer.removeAllViewsInLayout()
val questionWidget: QuestionWidget =
dataSource[position]
questionWidget.setValueChangedListener(this)
holder.linearLayoutContainer.addView(questionWidget)/*addView throws error once in a while*/
}
inner class QuestionWidgetViewHolder(mView: View) :
RecyclerView.ViewHolder(mView) {
val linearLayoutContainer: LinearLayout =
mView.findViewById(R.id.custom_question_widget_container)
}
R.id.custom_question_widget_container的内容:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/custom_question_widget_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="vertical"
android:padding="10dp" />
所以,questionWidget似乎已经在可见性之外保留了几乎4步的父,当我快速滚动到相反的方向时,我会遇到它仍然与它的父,然后我试图将它添加到另一个容器。
这里是解决方案-选项1:
override fun onBindViewHolder(holder: QuestionWidgetViewHolder, position: Int) {
holder.linearLayoutContainer.removeAllViewsInLayout()
val questionWidget: QuestionWidget =
dataSource[position]
questionWidget.setValueChangedListener(this)
val initialWidgetParent : ViewParent? = questionWidget.parent
//attempt to detach from previous parent if it actually has one
(initialWidgetParent as? ViewGroup)?.removeView(questionWidget)
holder.linearLayoutContainer.addView(questionWidget)
}
另一个更好的解决方案-选项2:
override fun onBindViewHolder(holder: QuestionWidgetViewHolder, position: Int) {
holder.linearLayoutContainer.removeAllViewsInLayout()
val questionWidget: QuestionWidget =
dataSource[position]
questionWidget.setValueChangedListener(this)
val initialWidgetParent : ViewParent? = questionWidget.parent
//if it's in a parent container already, just ignore adding it to a view, it's already visible
if(initialWidgetParent == null) {
holder.linearLayoutContainer.addView(questionWidget)
}
}
实际上,在将它添加到父节点之前,它需要询问子节点是否有父节点。