我有一个很长的ListView
,其中每行有一个ImageView
。如果我慢慢滚动列表(每行有不同的图标显示),它会显示正确的位图。
当我快速滚动ListView
时出现问题。碰巧许多图像没有加载到ImageView
中,使其保持透明。甚至以前显示的那些也慢慢滚动列表。
以下是getView()方法中应显示图标的代码:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
String name = ... //custom code to get the icon name to show
Bitmap bitmap = BitmapFactory.decodeFile(getIconsDir() + name + getIconsExt(), options);
holder.imgIcon.setImageBitmap(bitmap);
我在适配器的getView()
方法中回收convertView。
我确定该位图存在于该位置。
imgIcon
是该行ImageView
引用的ViewHolder
。
我也试过使用图像加载器(比如Picasso),但我得到了相同的结果。
有没有人以前经历过这个?
答案 0 :(得分:2)
不要在适配器的getView()
中进行位图解码。这将导致ListView滞后并且还非常快地填充RAM。
你应该:
ListView重新循环视图,设备内存可能无法保存所有加载的位图。甚至图像加载库也面临这个问题。
答案 1 :(得分:0)
是的,ListViews中的图像存在性能问题。 但是以任何方式预取图像是一种可以避免调用文件系统上的操作和二进制数据解码的方法。 我熄灭你将viewholder存储在convertviews - 标签中。
答案 2 :(得分:0)
从磁盘加载图像是一个缓慢的操作,因此将它们从存储在其中的任何压缩格式(如JPG或PNG)解码为位图。理想情况下,它不应该在主线程上的getView()中完成。而且,它们占用了大量的内存。
如果这些“图标”是静态的,您应该将它们包含为可绘制资源,然后使用ImageView.setImageResource。然后操作系统将弄清楚如何以最佳方式加载它们(另外,这样你就可以获得给定屏幕的正确分辨率)。
如果图标不是静态的(例如从网络加载),我建议使用带有异步加载器的内存缓存,但要确保它的大小有限和/或使用弱引用(但要注意:Android通常会建议反对使用弱/软引用,特别是对于位图,因为为位图分配的内存是本机代码,所以垃圾收集器不知道这些图像真正占用了多少内存,它可能决定不收集它们,即使它是内存不足...因为它认为它们很小。