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

Android 監聽多個 EditText 文本變化:單一 TextWatcher 配合類型標識的最佳實踐

     編輯:程式設計疑難解答

問題

4 個 `EditText` 需要相互聯動,各自設置 `TextWatcher` 代碼冗餘、難維護。

解決方案:帶類型參數的統一 TextWatcher


public class MultiEditTextWatcher implements TextWatcher {
    private final int type; // 區分不同 EditText
    private final EditText[] allEdits; // 所有關聯 EditText 引用

    public MultiEditTextWatcher(int type, EditText[] allEdits) {
        this.type = type;
        this.allEdits = allEdits;
    }

    @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
    
    @Override public void onTextChanged(CharSequence s, int start, int before, int count) {}
    
    @Override
    public void afterTextChanged(Editable s) {
        // 核心邏輯:根據 type 區分來源,更新其他 EditText
        switch (type) {
            case 0: // 編輯框 A 變化
                updateOthers(0, s.toString());
                break;
            case 1: // 編輯框 B 變化
                updateOthers(1, s.toString());
                break;
            // ... 其他 case
        }
    }

    private void updateOthers(int sourceIndex, String text) {
        for (int i = 0; i < allEdits.length; i++) {
            if (i == sourceIndex) continue; // 跳過來源
            // 關鍵:移除監聽 -> 設置文本 -> 重新添加,避免遞歸觸發
            EditText et = allEdits[i];
            et.removeTextChangedListener(this); // 需保持同一實例
            et.setText(computeNewText(i, text));
            et.addTextChangedListener(this);
        }
    }
    
    private String computeNewText(int targetIndex, String sourceText) {
        // 實際業務計算邏輯
        return sourceText; // 示例
    }
}

// 使用
EditText[] edits = {et1, et2, et3, et4};
for (int i = 0; i < edits.length; i++) {
    edits[i].addTextChangedListener(new MultiEditTextWatcher(i, edits));
}

關鍵技巧

  1. 同一實例監聽多個 View:構造函數傳入 `type` 和所有 `EditText` 引用,`afterTextChanged` 內 `switch(type)` 分發。
  2. 防遞歸觸發:程式修改其他 `EditText` 文本時,**必須**先 `removeTextChangedListener`,修改完再 `addTextChangedListener`,否則會陷入無限循環。
  3. 弱引用防洩漏:若 `EditText` 生命週期短於 Activity,建議在 `MultiEditTextWatcher` 中用 `WeakReference` 持有引用。

替代方案:RxTextView (RxBinding)


// 需引入 com.jakewharton.rxbinding3:rxbinding:3.1.0
Observable textChanges = RxTextView.textChanges(editText);
textChanges.subscribe(s -> { /* 反應式處理 */ });
// 多 EditText 合併
Observable.merge(RxTextView.textChanges(et1), RxTextView.textChanges(et2)...)
    .subscribe(...);

總結

單一 `TextWatcher` + `type` 模式碼量最少、邏輯集中、易擴展。核心注意點:**程式修改文本時暫時移除監聽器防遞歸**。

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