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

Android ListView 圖片錯位:異步載入與 ViewHolder 復用機制深度解析

     編輯:程式設計疑難解答

經典錯誤現場


holder.image.setTag(ranklist.get(position).getRank());
holder.image.setImageResource(R.drawable.ph_user);
// ... 異步載入 ...
if (holder.image.getTag().equals(position+1) ...) // 錯誤判斷

根本原因

  1. Tag 設定時機錯:setTag 應存**目標 URL/唯一標識**,而非 position(position 隨滾動變化)。
  2. 異步回調未驗證 Tag:圖片載入完成時,該 View 可能已被回收給其他 position,直接 setImageBitmap 會導致圖片錯位/閃爍。
  3. 同步/異步混用:代碼中同時有 setImageResource(同步)與 imageloader.displayImage(異步),邏輯衝突。

標準修正模式


String url = ranklist.get(position).getAvatar();
holder.image.setTag(url); // 1. Tag 存 URL
holder.image.setImageResource(R.drawable.placeholder); // 2. 先顯示佔位圖

if (!TextUtils.isEmpty(url)) {
    imageLoader.displayImage(url, holder.image, options, 
        new ImageLoadingListener() {
            @Override
            public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
                // 3. 關鍵:再次驗證 Tag 是否仍匹配
                if (url.equals(view.getTag())) {
                    ((ImageView)view).setImageBitmap(loadedImage);
                }
            }
            // ... 其他回調
        });
} else {
    holder.image.setImageResource(R.drawable.default_avatar);
}

現代最佳實踐

  • 棄用 ListView,**改用 RecyclerView + Glide/Picasso/Coil**,內建完整的請求取消、Tag 驗證、生命週期綁定。
  • 若必須維護 ListView,封裝通用 bindView(ViewHolder, int position) 邏輯,統一處理異步載入與 Tag 驗證。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved