问题描述
我有一个回收站视图。 我有许多不同内容类型的视图持有者。
我这样创建我的持有人:
/**
* 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。 我正在显示哈希标签(如果存在),因此在下面的第一项中:
然后,当我向下滚动到带有标签的第五项时(如下所示):
然后,当我向上滚动到第一项时,不应该添加标签,因为没有与此对象相关的标签数据(请参见下文):
我已经调试过,对象数据中没有混淆,没有通过代码添加标签,这取决于recyclerview的回收,这两个项目都具有相同的视图持有者(视图持有者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);
List<String> tagsList = feedContent.getTags(); if(tagsList.size>0)populateTags(tagsList, tagsArray);
这不仅发生在项目1和5上,还取决于要重用的视图。
如果存在已显示标签的视图重用的视图,则添加重用视图中的标签。
这很糟糕
1楼
基本上,RecyclerView是可回收的。 它会重用容器,但不会重置它们!
这意味着每次向ViewHolder填充数据时,都需要添加新数据和删除旧数据 (或隐藏一些Views )。 如果不这样做,最终将得到先前膨胀的对象的数据:-(
编辑:所以,如果您的膨胀代码中有类似的内容
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中,还需要防止没有数据放入其中的情况。
2楼
所以我发现这个问题在SO上 。
与上述问题相同,但建议的答案无效。
我注意到“这种情况通常发生在您拥有诸如“ if(field!= null)holder.setField(field)”之类的东西时,没有其他情况。该持有人被回收,这意味着它将在那里拥有价值,因此您需要清理或替换每个值,如果为null,则应将其为null;否则,应始终将其写入。这已经很晚了,但可以作为其他答案。”
在评论中。
所以我改变了从if(tagsList.size>0)populateTags(tagsList, tagsArray);
populateTags(tagsList, tagsArray);
因为我没有别的,而且逻辑在方法中。
就是这样..希望对其他人有帮助