首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Android ListView 圖片錯位/復用舊圖:異步加載 + Tag 機制徹底解決

     編輯:程式設計疑難解答

根因

ListView 復用 convertView,異步加載圖片時,請求發出 → 列表滾動 → convertView 被復用給新位置 → 圖片回調到來 → 寫入已屬於新位置的 ImageView,導致圖片錯亂。

解決方案:給 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:Glide.with(ctx).load(url).into(iv) 內部已實現 Tag 比對、生命週期綁定、內存/磁盤緩存。
  • Picasso / Coil(Kotlin) 同理。

核心原則

  1. 異步回調前**必須驗證目標 View 仍屬於原位置**(Tag 比對或請求取消)。
  2. 不要手寫線程池/緩存,除非極簡項目;成熟庫經過億級驗證。

加上 setTag/getTag 雙重校驗,ListView 圖片錯位問題徹底歸零。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved