Search code examples
androidandroid-edittextandroid-textinputedittext

How to sync two or more EditTexts in android?


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.


Solution

  • 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