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.
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