我正在RecyclerView
向我的项目动态添加视图。这些添加的视图应该只与它们被添加到的项目相关,但是当我滚动时我遇到了问题。似乎View
被回收并加载了一个新项目,但之前添加的视图仍在那里,现在只有错误的项目。
我假设这只是因为ViewHolder
被重复使用,所以添加的项目在加载后会再次显示新项目。
如何解决这个问题?
答案 0 :(得分:5)
这是我的一个老问题。奖金被放置在它上面,因此受欢迎程度的激增以及多个新的和不相关的答案。
正如我对this answer的评论和 @CQM 的评论中所说,我的原始问题,答案是覆盖onViewRecycled()
方法并执行那里需要的任何操作。当视图被回收时调用此方法,并且可以在此处完成任何清理操作。
可以找到有关此方法的文档here。
在我的情况下,这是删除附加到视图的不可见TextView
的问题。该文本本身已被删除,但观点仍然存在。如果许多不可见的TextView
在视图上累积,并且在滚动时没有正确回收,则滚动将开始滞后。
答案 1 :(得分:4)
您需要根据支持数据跟踪添加的视图。我可能会在onBindViewHolder()
中添加任何必要的额外视图,并删除onViewRecycled()
中可能存在的任何视图。然后,当您想要动态显示一个变量时,更改您跟踪的变量是否应该可见,并调用notifyItemChanged()
。
答案 2 :(得分:4)
基于此:
但之前添加的视图仍然存在,但现在错误的项目。
基本上,根据RecyclerView文档,您必须在onBindViewHolder()
方法中每次都重置视图,
所以说,你有一个方法可以设置查看参数,如果它是你的个人资料,所以相同的代码如下,
if (list.get(position).getId()==PreferenceManager.getUserID())
{
// do some view change here
setViewParam(true);
}else
{
// reset the view change here
setViewParam(false);
}
所以你在这里做的就是让回收的ViewHolder有机会重置。 如果您需要帮助,请发表评论!
答案 3 :(得分:4)
你可以用这个! setItemViewCacheSize(int size)
点击RecyclerViewDocumentation。
屏幕外视图缓存会随时了解附加适配器的更改,允许LayoutManager重新使用未经修改的视图,而无需返回适配器重新绑定它们。
答案 4 :(得分:1)
每次添加newView操作时,按标签为具有新子项的项目保存信息。 (例如共享偏好) 标签:使用项目位置onBindViewHolder创建。
...
SharedPreference sharedPref = getSharedPreference("text" + position, context);
SharedPreference.Editor editor = sharedPref.edit();
editor.putString("view", "ImageView");
...
当load Adapter获取此值并将default设置为null时。 我不确定它的效率,但我会工作。
...
String viewType = sharedPref.getString("view", null);
//it will return ImageView
如果你知道一些可能的viewTypes,例如总是会成为ImageView& TextView所以使用一些if语句就可以了。
if(viewType.equals("ImageVIew")){
item(position).addView(new ImageVIew(context));
}
祝你好运
答案 5 :(得分:1)
首先,您可以分享更多代码吗?
其次,为什么要在飞行中动态添加新视图?为什么不使用不同的VIEWTYPE或只是在布局上已经有这些视图,只是让它们可见/不可见或可见/消失? (我相信这样会更有效率。)
让我提醒你一些关于RecyclerView的信息,是的,当用户滚动viewHolder时正在重复使用(其中很少一部分可以创建,甚至超过了填充屏幕所需的数量)。因此,如果您在“项目A”上添加了一些视图并且用户滚动到“项目Z”,则该视图持有者可以重新用于该项目“Z”,从而显示之前添加的视图。
你怎么解决这个问题?
如果您需要添加新视图,请始终检查每个项目,如果是,则添加它们(如果尚未添加),否则始终删除这些视图(如果存在)以返回默认的viewHolder状态(或任何您称之为的)。 / p>
希望这会对你有所帮助。
答案 6 :(得分:0)
在recyclerView
的适配器类中,
在onBindViewHolder
方法中,
创建另一个适配器并为新适配器执行相同的方法。
层次结构将是,
mainRecyclerView - > item1( - > childRecyclerView1),item2( - > childRecyclerView2),item3( - > childRecyclerView3)
通过这种方式,您可以实现您想要的功能,而不会在错误的项目上查看错误的值。
答案 7 :(得分:0)
您应该在子项目布局Linearlayout
中采用XML
之类的任何空布局,然后在滚动列出所有人时以这种方式将视图添加到特定项目的LinearLayout
您添加到LinearLayout
的子视图也会滚动显示该项目。