ListView 在滑動加載數據時,偶爾出現項目重疊、殘留「陰影」或顯示錯亂的現象,必須重啟應用才能恢復。這通常發生在數據量大、項目佈局複雜或異步加載圖片的場景。
getView 中未正確重置 View 狀態(如圖片未清空、文字未更新、標籤 Tag 未清理),導致舊數據顯示在新項目上。wrap_content 且內容動態變化,導致 ListView 測量錯誤,滑動時位置計算偏差。@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.item_layout, parent, false);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
// 關鍵:每次綁定前重置狀態
holder.imageView.setImageResource(R.drawable.placeholder); // 設置佔位圖
holder.textView.setText(""); // 清空文字
// 綁定新數據
ItemData data = getItem(position);
holder.textView.setText(data.title);
imageLoader.load(data.url, holder.imageView); // 圖片加載庫自動處理取消/復用
return convertView;
}
static class ViewHolder {
TextView textView;
ImageView imageView;
ViewHolder(View view) {
textView = view.findViewById(R.id.tv_title);
imageView = view.findViewById(R.id.iv_icon);
}
}
推薦 Glide、Picasso 或 Coil。它們內部自動處理:
<!-- 在 AndroidManifest.xml 中 Application 或 Activity 標籤 -->
<application android:hardwareAccelerated="false" ...>
<!-- 或單獨關閉 ListView -->
listView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
RecyclerView 強制要求 ViewHolder 模式,提供 DiffUtil 高效更新,默認項目動畫更流暢,是 ListView 的現代替代品。
getView 是否每次都重置所有可見控件狀態?match_parent 或固定 dp?