我有一个回收者视图。对于不同的内容类型,我有很多观看者。
我创建了这样的持有者:
/**
* Create instance of
* compatible viewholder
*
* @param viewType
* @param parent
* @return
*/
private AbstractHolder createAbstractHolder(int viewType, ViewGroup parent) {
AbstractHolder holder = null;
switch (viewType) {
case VersyConstants.HOLDER_TYPE_1:
holder = ViewHolder_Var1.create(parent, mUserHomeFragment, mUserStreamFragment);
break;
case VersyConstants.HOLDER_TYPE_2:
holder = ViewHolder_Var2.create(parent, mUserHomeFragment, mUserStreamFragment);
break;
case VersyConstants.HOLDER_TYPE_3:
holder = ViewHolder_Var3.create(parent, mUserHomeFragment, mUserStreamFragment);
L.i(getClass().getSimpleName(), "HOLDER 3");
break;
case VersyConstants.HOLDER_TYPE_4:
holder = ViewHolder_Var4.create(parent, mUserHomeFragment, mUserStreamFragment);
L.i(getClass().getSimpleName(), "HOLDER 4");
break;
case VersyConstants.HOLDER_TYPE_5:
holder = ViewHolder_Var5.create(parent, mUserHomeFragment, mUserStreamFragment);
L.i(getClass().getSimpleName(), "HOLDER 5");
break;
case VersyConstants.HOLDER_TYPE_6:
holder = ViewHolder_Var6.create(parent, mUserHomeFragment, mUserStreamFragment);
L.i(getClass().getSimpleName(), "HOLDER 6");
break;
case VersyConstants.HOLDER_TYPE_7:
holder = ViewHolder_Var7.create(parent, mUserHomeFragment, mUserStreamFragment);
L.i(getClass().getSimpleName(), "HOLDER 7");
break;
case VersyConstants.HOLDER_TYPE_8:
holder = ViewHolder_Var8.create(parent, mUserHomeFragment, mUserStreamFragment);
L.i(getClass().getSimpleName(), "HOLDER 8");
break;
case VersyConstants.HOLDER_TYPE_9:
holder = ViewHolder_Var9.create(parent, mUserHomeFragment, mUserStreamFragment);
break;
case VersyConstants.HOLDER_TYPE_10:
holder = ViewHolder_Var10.create(parent, mThumbnailViewToLoaderMap, mUserHomeFragment, mUserStreamFragment);
}
return holder;
}
当我向下滚动回收器视图时,问题就出现了,例如,当我向上滚动到项目号时,为第一项和第五项创建了视图保持器3。 1,它有来自第5项的回收视图持有者,我知道这是回收者视图的想法。
在视图中,如果相关数据是JSON,我隐藏/显示textviews。我正在显示哈希标记(如果存在),所以在我的下面的第一个项目中:
然后,当我向后滚动到第一个项目时,标签会被添加,因为它们不应该是没有与此对象关联的标签数据(见下文):
我已经调试过了,对象数据没有混淆,没有通过代码添加标签,这是回收再循环视图,这两个项目都有相同的视图持有者(视图持有者3)。反正有没有阻止这个?
以下是填充标记的方法。根据列表大小,我将文本视图的可见性设置为可见并填充:
protected void populateTags(List<String>tags, TextView[] array){
for(int i=0;i<tags.size(); i++){
array[i].setText(tags.get(i));
array[i].setVisibility(View.VISIBLE);
}
}
我这样称呼List<String> tagsList = feedContent.getTags(); if(tagsList.size>0)populateTags(tagsList, tagsArray);
这不仅仅发生在第1项和第1项中。 5,它取决于哪些视图被重用。如果有一个视图重用于已显示标记的视图,则会添加重用视图中的标记。非常糟糕
答案 0 :(得分:3)
基本上,RecyclerView是回收利用。它重用了容器,但不会重置它们!
这意味着每次使用数据向ViewHolder充气时,您都需要添加新数据并删除旧数据(或隐藏一些视图)。如果不这样做,您将得到之前虚增对象的数据: - (
编辑: 所以,如果你在膨胀代码中有这样的东西
if(item.getTagsCount() > 0)
tags.setVisibility(View.VISIBLE);
您需要将其更新为此类
if(item.getTagsCount() > 0)
tags.setVisibility(View.VISIBLE);
else
tags.setVisibility(View.GONE);
或
if(item.getTagsCount() > 0)
tags.setVisibility(View.VISIBLE);
else if(item.getTagsCount() == 0)
tags.setVisibility(View.GONE);
当然,这只是一个示例性条件。请记住,您将一些数据放入ViewHolder,您还需要防止没有数据放在那里的情况。
答案 1 :(得分:0)
所以我在SO上发现了这个问题RecyclerView adapter taking wrong values。与上述问题相同,但建议的答案并不奏效。我注意到了#34;这通常发生在你有类似&#34; if(field!= null)holder.setField(field)&#34;,没有else的情况下。持有者被回收,这意味着它将具有值,所以你需要清理或替换每个值,如果它是null你应该nullit,如果不是,你应该写它,总是。已经很晚了,但作为别人的答案。&#34;在评论中。所以我改变了我的调用,从if(tagsList.size>0)populateTags(tagsList, tagsArray);
填充到populateTags(tagsList, tagsArray);
,因为我没有其他的东西,而且逻辑在方法中。
这就是它......希望它对别人有所帮助