我有一个应用程序可以在后台线程中下载一堆图像。在下载每个图标时,我将其添加到我的自定义适配器中的ArrayList中,该适配器是BaseAdapter的子类。 ListView中使用BaseAdapter的每一行都有一个ImageView。在getView中,我执行以下操作。
public View getView(int position, View convertView, ViewGroup parent) {
final MyCustomImageClass imageObject = data.get(position);
View vi = convertView;
if(convertView==null) {
vi = inflater.inflate(R.layout.list_row, null);
}
ImageView thumbnail = (ImageView)vi.findViewById(R.id.list_image);
File appDir = new File(Utils.getAppFilesDir() +"");
File imageFolder = new File(appDir, imageObject.getImageFolderName());
File imageDir = new File(imageFolder, imageObject.getIconFilename());
Log.e("myapp", "row image dir: " + imageDir.toString());
if(imageDir.exists()) {
Bitmap imageBitmap = BitmapFactory.decodeFile(imageDir.toString());
thumbnail.setImageBitmap(imageBitmap);
}
thumbnail.invalidate();
}
但我所看到的是thumbnail
正在重复使用旧图像。就像,前几行将具有相同的缩略图,即使我在logcat中看到它们的路径不同。
如何告诉ListView中的Image,它的ImageView有一个新的Bitmap图像?
答案 0 :(得分:0)
ListView
中的每一行都会被回收,因此当一个人离开屏幕时,下一个将继续使用该容器。您可能不满足新更新的if
上的ImageView
语句,因此图像未设置为您想要的,因此它只是重用旧的。确保您的imageDir.exists()
成功完成,以确保新视图能够正确更新。另外,我认为没有任何理由要求无效。
编辑:我明白为什么你现在正在调用invalidate()
,但它仍然没有必要。我建议使用ImageView
的默认图像,就像android提供的一样,然后执行以下操作:
if(imageBitmap != null)
thumbnail.setImageBitmap(imageBitmap);
else
thumbnail.setImageDrawable(R.drawable.content_picture);
其中R.drawable.content_picture
是默认的“无图片展示”图像,也是为XML文件中的ImageView
定义的图像。
最后,您应该考虑使用ViewHolder
来加速ListView
的呈现。以下是一个示例:How to implement a view holder?
如果我在这里说的话没有意义,那就请求澄清。
答案 1 :(得分:0)
适配器正在回收整个列表项,而不仅仅是图像。在等待新位图被解码时,您需要将图像资源重置为占位符。
作为旁注,你真的不应该在UI线程上读取磁盘或解码位图。 getView()方法应该可以非常快速地返回,这就排除了在那里做任何实际工作。查看开发指南,了解有关如何处理位图的好提示:
http://developer.android.com/training/displaying-bitmaps/index.html