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

Android ListView 重復數據:ArrayList 靜態引用導致數據累積

     編輯:程式設計綜合問答

現象

首次進入 ListView 顯示 1,2,3。按返回鍵退出再進入,顯示 1,2,3,1,2,3。每次進入數據疊加。

根因

ArrayList 為靜態成員變量或單例持有,且每次初始化未 clear()。Activity 重建時,同一列表實例被重複添加數據。

代碼證據


// 錯誤模式
public class MyActivity extends Activity {
    private static List<Map<String,Object>> listItems = new ArrayList<>(); // 靜態!
    private MyAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 未清空直接添加
        listItems.addAll(loadData()); 
        adapter = new MyAdapter(this, listItems);
        listView.setAdapter(adapter);
    }
}

修正方案

方案一:onCreate 中創建新列表 (推薦)


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    List<Map<String,Object>> listItems = new ArrayList<>(); // 局部新建
    listItems.addAll(loadData());
    adapter = new MyAdapter(this, listItems);
    listView.setAdapter(adapter);
}

方案二:復用列表但先清空


listItems.clear(); // 關鍵!
listItems.addAll(loadData());
adapter.notifyDataSetChanged();

方案三:ViewModel 持有數據 (架構組件)


public class MyViewModel extends ViewModel {
    public MutableLiveData> items = new MutableLiveData<>();
}
// Activity 中
viewModel = new ViewModelProvider(this).get(MyViewModel.class);
viewModel.items.observe(this, list -> adapter.submitList(list));

最佳實踐檢查清單

  • ✅ 數據源不作為 static 字段持有。
  • ✅ 每次綁定前 clear() 或重新 new ArrayList()。
  • ✅ Adapter 內部不持有外部列表引用,必要時防御性拷貝 new ArrayList<>(source)。
  • ✅ 使用 DiffUtil / ListAdapter 實現增量更新,避免 notifyDataSetChanged() 全量刷新。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved