解决ListView上下快速滑动过程中头像消失问题,
主要原因为:
使用了定义软引用 Map<String, SoftReference<Bitmap>> 在快速滑动时,系统将内存中的头像回收导致
解决办法:
使用强引用定义 LruCache<String, Bitmap> iconCache = new LruCache<String, Bitmap>((int) (Runtime.getRuntime().maxMemory() / 8)); 用意在任何情况时都不进行回收。
关键代码如下:
1.开启线程用于 LruCache储存查询到的头像资源,完毕后通知适配器更新。
//开启线程用于 LruCache储存查询到的头像资源
public void swapData() {
this.mlist = MyApplication.getMyApplication().getContacts();
new Thread(new Runnable() {
@Override
public void run() {
for (PhoneNumberModel model : mlist) {
if (HeadImageUtils.isIcon(mContext, model.getContactId()
+ "")) {
if (iconCache.get(model.getContactId() + "") == null) {
Bitmap bitmap = HeadImageUtils.queryContactsBitmap(
mContext, model.getContactId());
// iconCache.put(model.getContactId() + "",
// new SoftReference<Bitmap>(bitmap));
iconCache.put(model.getContactId() + "", bitmap);
// Bundle bundle = new Bundle();
Message mesg = new Message();
mesg.what = 0;
}
}
}
handler.sendEmptyMessage(0);
}
}).start();
2.主线程UI接收消息msg.what == 0 通知并刷新头像
//接收adapter通知刷新
public Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
if (msg.what == UPDATE_VIEW) {
loaderCollectionContacts();
}else if(msg.what == 0){
contactsListAdapter.notifyDataSetChanged();
}
};
};
3.在getView()方法中根据联系人的ID作为key从内存中获取相应的头像图片,再将其设置在相应的控件上。
在这要注意的一个问题是在设置头像图片的时候要在else中判断在if中设置的标识tag是否跟现在的联系人ID相同,在不相同的情况下对控件中设置过的数据进行清除操作:。
ps:联系人ID = TAG
//获取缓冲中的头像并设置
if (iconCache.get(model.getContactId() + "") != null) {
holder.head.setImageBitmap(iconCache.get(model.getContactId()+""));
holder.head.setTag(model.getContactId());
} else {
if (holder.head.getTag() != null
&& !(model.getContactId() + "").equals(holder.head.getTag()
.toString())) {
holder.head.setImageBitmap(null);
}
}