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

Android ListView遍歷保存Item數據:ViewHolder復用機制下的正確姿勢

     編輯:程式設計綜合問答

ListView的`convertView`復用機制導致**無法直接遍歷所有Item View獲取數據**(非可見項View不存在/被復用)。正確做法是實時同步數據到模型層(數據源集合),最後遍歷數據源。本文詳解HashMap輔助方案與最佳實踐。

核心誤區

❌ 嘗試 `for (int i=0; i

正確架構:數據驅動視圖


// 1. 數據模型類
class TempRecord {
    String time;
    String temperature;
    boolean isValid;
}

// 2. 數據源列表(單一真實來源)
List dataList = new ArrayList<>();

// 3. Adapter中實時同步
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    if (convertView == null) {
        holder = new ViewHolder();
        convertView = inflater.inflate(R.layout.item_temp, parent, false);
        holder.timeTv = convertView.findViewById(R.id.time);
        holder.tempEt = convertView.findViewById(R.id.temperature);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    final TempRecord record = dataList.get(position);
    holder.timeTv.setText(record.time);
    holder.tempEt.setText(record.temperature);

    // 4. 關鍵:輸入框實時監聽,直接更新模型
    holder.tempEt.addTextChangedListener(new TextWatcher() {
        @Override public void afterTextChanged(Editable s) {
            record.temperature = s.toString(); // 即時寫回數據源
        }
        @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
        @Override public void onTextChanged(CharSequence s, int start, int before, int count) {}
    });

    // 時間選擇器同理更新 record.time
    return convertView;
}

輔助方案:HashMap暫存(適用於不想改模型類)


// 全局/Activity級 Map tempInputs = new HashMap<>();
// Map timeInputs = new HashMap<>();

// 在 getView 中:
holder.tempEt.addTextChangedListener(new TextWatcher() {
    @Override public void afterTextChanged(Editable s) {
        tempInputs.put(position, s.toString()); // 實時存
    }
    // ...
});

// 最後保存時遍歷 Map:
for (int i = 0; i < dataList.size(); i++) {
    String temp = tempInputs.get(i);
    String time = timeInputs.get(i);
    // 組裝保存
}

關鍵最佳實踐

  1. 拒絕遍歷View樹:ListView/RecyclerView核心機制決定了View非持久化。
  2. 單一數據源原則:所有用戶輸入即時寫入模型/Map,UI只是數據的投影。
  3. 去抖動優化:頻繁輸入場景(如搜索框)用`Debounce`/RxJava `debounce`減少寫入頻率。
  4. 輸入驗證:保存前遍歷數據源檢查完整性/合法性。
  5. 遷移RecyclerView**:`RecyclerView.ViewHolder` + `ListAdapter` + `DiffUtil` 更現代、高效、穩健。

場景總結

場景推薦方案
少量固定項(<10)、無復用LinearLayout + 手動addView,可直接遍歷子View
列表、動態項、需復用ListView/RecyclerView + **模型實時同步**
複雜表單、多類型項RecyclerView + 多ItemType + 數據綁定庫
鐵律:數據變,UI跟著變;UI變,數據要先變。別想著去問View要數據,View只負責顯示。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved