0

I want to use three EditTexts and when the user changes the content of one EditText the changes should be reflected in other two EditTexts.This behaviour should be the same with all the EditTexts. Let's say e1,e2,e3 are the id's of three Edittexts and when user inputs something in e1, e2 and e3 must be assigned the value from the e1. If e2 is changed then e1 and e3 must be assigned the value from the e2.

Pritam
  • 339
  • 3
  • 23
maneesh reddy
  • 13
  • 1
  • 3
  • You can use the interface`.onTextChange` on all your editTexts, and decide what to do when the text get changed in each one of them – Codey Jun 03 '18 at 13:02

3 Answers3

2

You can use this custom made TextWatcher

example :

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

}

and this is 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);
    }
}
Amir Hossein Mirzaei
  • 2,325
  • 1
  • 9
  • 17
1

I think it's should look like this.

Example to set the text on e2 and e3 after the text on e1 is changed

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
    } 
});
Paul Chu
  • 1,249
  • 3
  • 19
  • 27
Codey
  • 460
  • 1
  • 8
  • 23
1

Here is my solution

Write a custom 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);
        }
    }
}

Usage

<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" />

Set dependencies in code:

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);

All of the SyncEditText now fire an event to all its dependencies, an additional flag is added to make sure there is no text changed loop

Tam Huynh
  • 2,026
  • 1
  • 16
  • 20