如何同步 android 中的两个或多个 EditText?

How to sync two or more EditTexts in android?

我想使用三个 EditText,当用户更改一个 EditText 的内容时,更改应该反映在其他两个 EditTexts.This 行为应该与所有 EditText 相同。 假设 e1、e2、e3 是三个 Edittext 的 ID,当用户在 e1 中输入内容时,必须为 e2 和 e3 分配来自 e1 的值。 如果更改了 e2,则必须为 e1 和 e3 分配 e2 中的值。

我觉得应该是这样的。

更改 e1 上的文本后设置 e2 和 e3 上的文本的示例

e1.addTextChangedListener(new TextWatcher() {
    @Override
    public void afterTextChanged(Editable s) {
       e2.setText(...what you want to do);
       e3.setText(...what you want to do);
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        // TODO Auto-generated method stub
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        // TODO Auto-generated method stub
    } 
});

这是我的解决方案

写一个自定义SyncEditText:

public class SyncEditText extends AppCompatEditText implements TextWatcher {
    private SyncEditText[] mDependencies;
    private boolean shouldSync = true;

    public SyncEditText(Context context) {
        super(context);
    }

    public SyncEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public SyncEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        // This is to avoid text changed event is called multiple time per character because auto suggestion
        setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);

        addTextChangedListener(this);
    }

    public void setDependencies(SyncEditText... dependencies) {
        mDependencies = dependencies;
    }

    public void setText(CharSequence text, boolean syncDependencies) {
        shouldSync = syncDependencies;
        setText(text);

        Log.d("Log", "Text sync: " + text);
    }

    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { }

    @Override
    public void afterTextChanged(Editable editable) { }

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
        if (mDependencies == null)
            return;

        if (!shouldSync) {
            // If this text is sync from other SyncEditText, ignore the change
            shouldSync = true;
            return;
        }

        Log.d("Log", "Text input: " + charSequence);

        // Sync to all dependencies
        for (SyncEditText syncEditText : mDependencies) {
            syncEditText.setText(charSequence, false);
        }
    }
}

用法

<com.example.tamhuynh.testfragment.SyncEditText
    android:id="@+id/txt_1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

<com.example.tamhuynh.testfragment.SyncEditText
    android:id="@+id/txt_2"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

<com.example.tamhuynh.testfragment.SyncEditText
    android:id="@+id/txt_3"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

在代码中设置依赖:

SyncEditText editText1 = findViewById(R.id.txt_1);
SyncEditText editText2 = findViewById(R.id.txt_2);
SyncEditText editText3 = findViewById(R.id.txt_3);

editText1.setDependencies(editText2, editText3);
editText2.setDependencies(editText1, editText3);
editText3.setDependencies(editText1, editText2);

所有 SyncEditText 现在都会向其所有依赖项触发一个事件,添加一个额外的标志以确保没有文本更改循环

您可以使用这个定制的 TextWatcher

示例:

    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    SyncTextWatcher syncTextWatcher=new SyncTextWatcher();
    syncTextWatcher.addEditText(
            (EditText)findViewById(R.id.editText1),
            (EditText)findViewById(R.id.editText2),
            (EditText)findViewById(R.id.editText3),
            (EditText)findViewById(R.id.editText4),
            (EditText)findViewById(R.id.editText5)
    );

}

这是 SyncTextWatcher Class

class SyncTextWatcher implements TextWatcher {

    private List<EditText> editTexts = new ArrayList<>();


    @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) {

        for (int i = 0; i < editTexts.size(); i++) {


            EditText editText = editTexts.get(i);

            if(editText.getText()==s)continue;

            editText.removeTextChangedListener(this);

            editText.setText(s.toString());

            editText.addTextChangedListener(this);
        }

    }

    public void addEditText(EditText... editTexts) {
        for (int i = 0; i < editTexts.length; i++){
            this.editTexts.add(editTexts[i]);
            editTexts[i].addTextChangedListener(this);
        }
    }

    public void removeEditText(EditText editText) {
        boolean b = editTexts.remove(editText);
        if (b) editText.removeTextChangedListener(this);
    }
}