我用类似的方法来回答这个问题。唯一真正的区别是,我不是基于SoftReference<Bitmap
的缓存,而是将图像保存到/data/data/my.app/files
,因为它们预计不会经常更改。我的适配器的getView()
功能:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//data from your adapter
MyItem entry = getItem(position);
//we want to reuse already constructed row views...
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.appitem, null);
}
convertView.setTag(entry);
TextView Name = (TextView)convertView.findViewById(R.id.Name);
TextView Version = (TextView)convertView.findViewById(R.id.Version);
final ImageView Icon = (ImageView)convertView.findViewById(R.id.Icon);
Name.setText(entry.getName());
Version.setText(entry.getVersion());
Icon.setImageResource(R.drawable.default_icon); // the problem line
try {
final String _id = entry.getID();
imageLoader.loadImage(_id, "<my url>", new ImageThreadLoader.ImageLoadedListener() {
public void imageLoaded(Bitmap imageBitmap) {
Icon.setImageBitmap(imageBitmap);
notifyDataSetChanged();
}
});
} catch (Throwable t) {
Log.e("","", t); // nothing is hitting this log
}
return convertView;
}
上面标记的"问题行",我将图标设置为默认图标,如果我删除该行,那么一切正常(当重用视图时,它会在显示新图像之前不久显示旧图像)。如果该行存在,则图像永远不会更改为其他任何内容。匿名ImageLoadedListener
仍在 UI 线程上运行,在那里设置断点显示一切似乎都在正常发生。我也知道ImageThreadLoader
工作正常。文件出现在它们应该出现的地方,看起来很好(当删除上面的问题行时,它们加载得很好)。
为什么提前设置映像会导致以后无法更新?
感:
删除 notifyDataSetChanged()。
为什么?调用适配器.notifyDataSetChanged() 将引发列表(即:每个视图)的完全刷新。因此,对每个项目进行新的调用 getView(position)。在此调用中,您将再次将图像更改为default_icon。这在设置好之后附加!
所以顺序是:为一个图像设置default_icon,从磁盘加载一个图像,使 -> 为 ALL 设置默认值,从磁盘加载一个图像,....
编辑:澄清解释,删除有关线程限制的假设。