4 個 `EditText` 需要相互聯動,各自設置 `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));
}
// 需引入 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` 模式碼量最少、邏輯集中、易擴展。核心注意點:**程式修改文本時暫時移除監聽器防遞歸**。