我有ListView
个自定义ArrayAdapter
。此ListView
中的每一行都有一个图标和一些文本。这些图标在后台下载,缓存,然后使用回调,在各自的ImageViews
中替换。每次getView
()运行时都会触发从缓存或下载中获取缩略图的逻辑。
现在,据罗曼盖伊说:
“绝对没有保证 getView()的顺序 叫了也没多少次。“
我已经看到过这种情况,因为一行大小为2的getView()被调用了六次!
如何更改代码以避免重复的缩略图获取请求并处理视图回收?
感谢。
答案 0 :(得分:14)
确切地说,这可能发生在例如你有
的时候android:layout_height="wrap_content"
在ListView
定义中。将它改为fill_parent / match_parent会避免它。
答案 1 :(得分:8)
来自api。
public abstract View getView (int position, View convertView,
ViewGroup parent)
convertView - 如果可能,重用旧视图。注意:在使用之前,应检查此视图是否为非null且类型是否合适。如果无法转换此视图以显示正确的数据,则此方法可以创建新视图。
因此,如果已经为此特定索引调用了getView,那么convertView将是从第一次调用返回的View对象。
你可以做类似的事情。
if(!(convertView instanceof ImageView)){
convertView = new ImageView();
//get image from whereever
} else {} // ImageView already created
答案 2 :(得分:1)
我正在尝试同样的问题,我将listView的layout_height更改为match_parent解决了我的问题。
答案 3 :(得分:1)
我的理解是你需要在这里使用ViewHolder设计模式。只使用返回的convertView可以导致重用前一个视图(在这种情况下分配了一些其他图像)。
public class ImageAdapter extends ArrayAdapter<String> {
// Image adapter code goes here.
private ViewHolder {
public ImageView imageView;
public String url;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = null;
ViewHolder viewHolder;
String url = getUrl(position);
if (convertView == null) {
// There was no view to recycle. Create a new view.
view = inflator.inflate(R.layout.image_layout, parent, false);
viewHolder = new ViewHolder();
viewHolder.imageView = (ImageView) view.findViewById(R.id.image_view);
viewHolder.url = url;
view.setTag(viewHolder);
} else {
// We got a view that can be recycled.
view = convertView;
viewHolder = ((ViewHolder) view.getTag());
if (viewHolder.url.equals(url)) {
// Nothing to do, we have the view with the correct info already.
return view;
}
}
// Do work to set your imageView which can be accessed by viewHolder.imageView
return view;
}
}
答案 4 :(得分:0)
更好的方法是使用缩略图(位图)和文本创建对象。如果缩略图在对象中不可用,请阅读缩略图。
答案 5 :(得分:0)
在适配器中创建一个ImageView对象数组,并在检索它们时缓存它们(无论是从缓存还是Web)。例如,在getView中,在获取ImageView之前,检查它是否已经在您的本地数组中,如果是这样,使用它,如果不是fetch,一旦在本地ImageView数组中收到存储以供将来使用。
答案 6 :(得分:0)
我的Fragment.xml有一个ListView,这个ListView的布局设置是 android:layout_height =“wrap_content”,这个ListView稍后会绑定到SimpleCursorAdapter。然后我在ViewBinder中遇到同样的问题被调用3次。将layout_height =“wrap_content”更改为“95p”后问题得以解决。我确实认为“wrap_content”高度导致了这个问题。 尝试修改Fragment.xml,我想3次调用将不再存在。