滚动时ArrayAdapter顺序get的ListView混合起来

我有一个自定义ArrayAdapter中的ListView,每行显示一个图标ImageView和一个TextView。 当我列出足够长的时间让你滚动浏览它时,顺序开始正确,但是当我开始向下滚动时,一些较早的条目开始重新出现。 如果我向后滚动,旧的顺序会改变。 重复这样做最终导致整个列表顺序看起来是随机的。 因此,滚动列表要么导致子订单更改,要么graphics不正确刷新。

什么可能导致这样的事情发生? 我需要向用户显示的项目顺序与添加到ArrayList中的顺序相同,或者至less保持一个静态顺序。 如果我需要提供更详细的信息,请告诉我。 任何帮助表示赞赏。 谢谢。

我有类似的问题,但是当点击自定义列表中的项目时,屏幕上的项目将按顺序颠倒。 如果我再次点击,他们会扭转回原来的位置。

读完这个之后,我检查了我的代码,我重载了getView方法。 我从转换后的视图中得到了视图,如果它是空的,那就是当我构build我的东西的时候。 然而,放置一个断点后,我发现它在每次点击和随后的点击都调用这个方法时,转换的视图不是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; } 

我希望这可以帮助那些遇到同样问题的人。

为了进一步澄清下面更为一般的farcats的答案,这里是我的解释:

vi.inflate操作(这里需要从XMLparsing一行的布局并创build相应的View对象)由if(view == null)语句包装以提高效率,所以同一对象的通货膨胀不会发生它每次都会一次又一次地出现在视图中。

但是,getView方法的其他部分用于设置其他参数,因此不应包含在if(view == null)语句中。

类似地,在这个方法的其他常见实现中,一些textView,ImageView或者ImageButton元素需要使用findViewById.setText或者.setImageBitmap操作来填充list [position]中的值。 这些操作必须在通过通货膨胀从头开始创build一个视图, 获得一个现有的视图,如果不是空的。

在BaseAdapter中应用此解决scheme的另一个很好的示例出现在BaseAdapter中,导致ListView滚动时出现乱序

滚动时,ListView重用视图对象。 你重写getView方法吗? 你需要确定你为每个视图设置了每个属性,不要以为它会记住你以前的东西。 如果您发布该方法,则可能有人可能会将您指向不正确的部分。

我有一个ListView,AdapterView和包含EditText和3个Spinners的视图(search_options)。 ListView项目是(search_options)布局的多个副本,其中用户可以在ListView中添加更多选项,然后单击search按照用户选项发送构build的SQL查询。

我发现convertView混合indecies所以我在活动中添加一个全局列表(myViews)并将其传递给ArrayAdapter。 然后在ArrayAdapter(getView)中添加每个新添加的视图(myViews)。

另外,在getView而不是检查convertView是否为空,我检查全局列表(myViews)是否有选定的位置(位置)的视图..它完全解决问题后,失去了3天的互联网阅读!

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; } 

最后没有更多的混合项目…