[英]ListView in ArrayAdapter order get's mixed up when scrolling
我在自定义ArrayAdapter中有一个ListView,该数组在每行中显示一个ImageImageView和一个TextView。 当我使列表足够长以使您可以滚动列表时,该顺序从右开始,但是当我开始向下滚动时,一些较早的条目开始重新出现。 如果我向上滚动,旧的顺序会改变。 重复执行此操作最终会导致整个列表顺序看似随机。 因此,滚动列表会导致子顺序更改,或者图形无法正确刷新。
什么会导致这种情况发生? 我需要将项目显示给用户的顺序与它们添加到ArrayList的顺序相同,或者至少保持一个静态顺序。 如果我需要提供更多详细信息,请告诉我。 任何帮助表示赞赏。 谢谢。
我遇到了类似的问题,但是单击自定义列表中的项目时,屏幕上的项目将依次颠倒。 如果我再次单击,它们会退回到原来的位置。
阅读此内容后,我检查了我的代码,在其中我重载了getView方法。 我是从convertedView获取视图的,如果它为null,那就是在构建自己的东西时。 但是,在放置断点后,我发现它在每次单击以及随后的单击时都调用此方法,convertedView不为null,因此未设置项目。
这是一个例子:
public View getView(int position, View convertView, ViewGroup parent)
{
View view = convertView;
if (view == null)
{
LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = vi.inflate(R.layout.listitemrow, null);
RssItem rssItem = (RssItem) super.getItem(position);
if (rssItem != null)
{
TextView title = (TextView) view.findViewById(R.id.rowtitle);
if (title != null)
{
title.setText(rssItem.getTitle());
}
}
}
return view;
}
细微的变化是将视图上的空检查的右括号移动到膨胀后:
public View getView(int position, View convertView, ViewGroup parent)
{
View view = convertView;
if (view == null)
{
LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = vi.inflate(R.layout.listitemrow, null);
}
RssItem rssItem = (RssItem) super.getItem(position);
if (rssItem != null)
{
TextView title = (TextView) view.findViewById(R.id.rowtitle);
if (title != null)
{
title.setText(rssItem.getTitle());
}
}
return view;
}
希望这对遇到同样问题的其他人有所帮助。
为了以更一般的方式进一步阐明以下Farcat的答案,以下是我的解释:
vi.inflate操作(此处是从XML解析行的布局并创建适当的View对象所需的操作)由if(view == null)语句包装,以提高效率,因此不会发生同一对象的膨胀一次又一次地出现在视图中。
但是,getView方法的其他部分用于设置其他参数,因此不应包含在if(view == null)语句中。
相若方式,在其他常见的实现该方法,一些TextView的的,ImageView的或ImageButton的元件需要由值从列表[位置]填充,使用findViewById并且之后.setText或.setImageBitmap操作。 这些操作必须来都受通胀从头开始创建一个视图,并让现有视图如果不为空后。
另一个适用于BaseAdapter的解决方案的好示例出现在BaseAdapter中,导致滚动时ListView出现故障
滚动时,ListView重用视图对象。 您要覆盖getView方法吗? 您需要确保为每个视图都设置了每个属性,不要以为它会记住您以前拥有的内容。 如果您发布该方法,则有人可能会指出您不正确的部分。
我有一个ListView,AdapterView和一个包含EditText和3 Spinners的视图(search_options)。 ListView项目是(search_options)布局的多个副本,用户可以在ListView中添加更多选项,然后单击“搜索”以发送根据用户选项构建的sql查询。
我发现convertView的混合效果不确定,因此我在活动中添加了一个全局列表(myViews),并将其传递给ArrayAdapter。 然后在ArrayAdapter(getView)中,将每个新添加的视图添加到其中(myViews)。
同样在getView上,而不是检查convertView是否为null,我检查全局列表(myViews)是否具有选定位置(位置)上的视图。在丢失三天的互联网阅读时间后,它完全解决了问题!
1-在活动上添加以下内容:
Map<Integer, View> myViews = new HashMap<>();
然后使用适配器构造函数将其传递给ArrayAdapter。
mSOAdapter = new SearchOptionsAdapter(getActivity(), resultStrs, myViews);
2-在getView上:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view;
ViewHolder viewHolder;
if (!myViews.containsKey(position)) {
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
view = inflater.inflate(R.layout.search_options, parent, false);
/// ...... YOUR CODE
myViews.put(position, view);
FontUtils.setCustomFontsIn(view, getContext().getAssets());
}else {
view = myViews.get(position);
}
return view;
}
终于没有更多的混合项目了...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.