ListView 復用 convertView,異步加載圖片時,請求發出 → 列表滾動 → convertView 被復用給新位置 → 圖片回調到來 → 寫入已屬於新位置的 ImageView,導致圖片錯亂。
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.item, parent, false);
holder = new ViewHolder();
holder.iv = convertView.findViewById(R.id.iv);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
String url = getItem(position).imageUrl;
holder.iv.setTag(url); // 1. 標記當前應顯示的 URL
holder.iv.setImageResource(R.drawable.placeholder);
imageLoader.load(url, new Callback() {
@Override public void onSuccess(Bitmap bmp) {
if (url.equals(holder.iv.getTag())) { // 2. 回調時比對 Tag
holder.iv.setImageBitmap(bmp);
}
}
@Override public void onFail() { /* 保持佔位圖 */ }
});
return convertView;
}
Glide.with(ctx).load(url).into(iv) 內部已實現 Tag 比對、生命週期綁定、內存/磁盤緩存。加上 setTag/getTag 雙重校驗,ListView 圖片錯位問題徹底歸零。