Как использовать Single TextWatcher для нескольких EditTexts?

У меня есть три виджета EditText в макете просмотра. Есть ли способ использовать один TextWatcher для всех трех EditTexts ?

Я просто столкнулся с этой проблемой. Я решил это, создав внутреннюю реализацию класса TextWatcher которая принимает представление как аргумент. Затем в реализации метода просто включите представление, чтобы увидеть, какой из них Editable

Декларация:

 private class GenericTextWatcher implements TextWatcher{ private View view; private GenericTextWatcher(View view) { this.view = view; } public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {} public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {} public void afterTextChanged(Editable editable) { String text = editable.toString(); switch(view.getId()){ case R.id.name: model.setName(text); break; case R.id.email: model.setEmail(text); break; case R.id.phone: model.setPhone(text); break; } } } 

Применение:

 name = (EditText) findViewById(R.id.name); name.setText(model.getName()); name.addTextChangedListener(new GenericTextWatcher(name)); email = (EditText) findViewById(R.id.email); email.setText(model.getEmail()); email.addTextChangedListener(new GenericTextWatcher(email)); phone = (EditText) findViewById(R.id.phone); phone.setText(model.getPhone()); phone.addTextChangedListener(new GenericTextWatcher(phone)); 

Если вы хотите использовать только afterTextChanged, сравните редактируемые файлы:

 @Override public void afterTextChanged(Editable editable) { if (editable == mEditText1.getEditableText()) { // DO STH } else if (editable == mEditText2.getEditableText()) { // DO STH } } 

Он будет работать с этим кодом

 TextWatcher watcher = new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { //YOUR CODE } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { //YOUR CODE } @Override public void afterTextChanged(Editable s) { String outputedText = s.toString(); mOutputText.setText(outputedText); } }; 

Затем добавьте это в oncreate

  mInputText.addTextChangedListener(watcher); e2.addTextChangedListener(watcher); e3.addTextChangedListener(watcher); e4.addTextChangedListener(watcher); 

Внедрение MultiTextWatcher

 public class MultiTextWatcher { private TextWatcherWithInstance callback; public MultiTextWatcher setCallback(TextWatcherWithInstance callback) { this.callback = callback; return this; } public MultiTextWatcher registerEditText(final EditText editText) { editText.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { callback.beforeTextChanged(editText, s, start, count, after); } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { callback.onTextChanged(editText, s, start, before, count); } @Override public void afterTextChanged(Editable editable) { callback.afterTextChanged(editText, editable); } }); return this; } interface TextWatcherWithInstance { void beforeTextChanged(EditText editText, CharSequence s, int start, int count, int after); void onTextChanged(EditText editText, CharSequence s, int start, int before, int count); void afterTextChanged(EditText editText, Editable editable); } } 

Применение

  new MultiTextWatcher() .registerEditText(editText1) .registerEditText(editText2) .registerEditText(editText3) .setCallback(new TextWatcherWithInstance() { @Override public void beforeTextChanged(EditText editText, CharSequence s, int start, int count, int after) { // TODO: Do some thing with editText } @Override public void onTextChanged(EditText editText, CharSequence s, int start, int before, int count) { // TODO: Do some thing with editText } @Override public void afterTextChanged(EditText editText, Editable editable) { // TODO: Do some thing with editText } }); 

Наследовать свой класс от Activity и реализовать TextWatcher.

Затем через магию полиморфизма вам просто нужно подписаться на события.

Это не скажет вам, что изменил TextEdit, однако, используя комбинацию этого и ответ Sky Kelsey , вы могли бы разобраться в этом красиво.

  public YourActivity extends Activity implements TextWatcher { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_YourActivity); //Subscribe to the events EditText txt1 = (EditText) findViewById(R.id.txt1); txt1.addTextChangedListener(this); EditText txt2 = (EditText) findViewById(R.id.txt2); txt2.addTextChangedListener(this); } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { EditText txt1 = (EditText) findViewById(R.id.txt1); EditText txt2 = (EditText) findViewById(R.id.txt2); // You probably only want the text value from the EditText. But you get the idea. doStuff(txt1,txt2); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.calc, menu); return true; } @Override public void afterTextChanged(Editable s) { // TODO Auto-generated method stub } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { // TODO Auto-generated method stub } } 

Я знаю, что это старая проблема, и есть правильное решение. Я напишу их, может быть, это поможет кому-то.

Эмулируя классический пример, где у нас есть N EditText, и мы хотим показать кнопку, если все поля заполнены. Этот пример имеет смысл, особенно если использовать валидаторы для каждого из них.

Я сделал пример в отношении этой проблемы, но вы можете сделать любой набор

MultiEditText.class

 public class MultiEditText extends AppCompatActivity{ EditText ed_1, ed_2, ed_3; Button btn_ok; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.multi_edit_text); ed_1 = (EditText) findViewById(R.id.ed_1); ed_2 = (EditText) findViewById(R.id.ed_2); ed_3 = (EditText) findViewById(R.id.ed_3); btn_ok = (Button) findViewById(R.id.btn_ok); btn_ok.setEnabled(false); //if want more here can cycle interface List 
  EditText[] edList = {ed_1, ed_2, ed_3}; CustomTextWatcher textWatcher = new CustomTextWatcher(edList, btn_ok); for (EditText editText : edList) editText.addTextChangedListener(textWatcher); 
  } } 

Это выглядит очень просто, теперь

CustomTextWatcher.class

 public class CustomTextWatcher implements TextWatcher { View v; EditText[] edList; public CustomTextWatcher(EditText[] edList, Button v) { this.v = v; this.edList = edList; } @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 (EditText editText : edList) { if (editText.getText().toString().trim().length() <= 0) { v.setEnabled(false); break; } else v.setEnabled(true); } } } 

Я добавлю макет, чтобы вы не тратили время

multi_edit_text.xml

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="16dp"> <EditText android:id="@+id/ed_1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_marginTop="8dp" /> <EditText android:id="@+id/ed_2" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/ed_1" android:layout_centerHorizontal="true" android:layout_marginTop="8dp" /> <EditText android:id="@+id/ed_3" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/ed_2" android:layout_centerHorizontal="true" android:layout_marginTop="8dp" /> <Button android:id="@+id/btn_ok" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/ed_3" android:layout_centerHorizontal="true" android:layout_marginTop="8dp" android:text="OK" /> </RelativeLayout> 
 TextWatcher watcher = new TextWatcher(){ @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void afterTextChanged(Editable editable) { } }; 

Затем:

 editText1.addTextChangedListener(watcher); editText2.addTextChangedListener(watcher); editText3.addTextChangedListener(watcher); 

Вот как я это сделал:

Создайте ArrayList из EditTexts, а затем используйте цикл for, чтобы применить TextWatcher для всех EditTexts, если у вас есть одно поведение для всех editTexts, а затем просто примените его там, если у вас есть определенные поведения для некоторых конкретных editTexts, тогда вы можете использовать if Заявление для выбора и применения к отдельным editTexts … вот мой код:

  ArrayList<EditText> editTexts = new ArrayList<>(); // Container list editText1 = (EditText) findViewById(R.id.editText1); editText2 = (EditText) findViewById(R.id.editText2); editText3 = (EditText) findViewById(R.id.editText3); editTexts.add(editText1); // editTexts[0] editTexts.add(editText2); // editTexts[1] editTexts.add(editText3); // editTexts[2] for (final EditText editText : editTexts) { //need to be final for custom behaviors editText.addTextChangedListener(new TextWatcher() { @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) { //Apply general behavior for all editTexts if (editText == editTexts.get(1)) { //Apply custom behavior just for this editText } } }); } 

Надеюсь это поможет

 public class MainActivity extends AppCompatActivity{ EditText value1, value2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //instantiate EditText controls value1 = (EditText)findViewById(R.id.txtValue1); value2 = (EditText)findViewById(R.id.txtValue2); //set up text changed listener value1.addTextChangedListener(new TextChange(value1)); value2.addTextChangedListener(new TextChange(value2)); //inner class private class TextChange implements TextWatcher { /** * This method is called to notify you that, within <code>s</code>, * the <code>count</code> characters beginning at <code>start</code> * are about to be replaced by new text with length <code>after</code>. * It is an error to attempt to make changes to <code>s</code> from * this callback. * * @param s * @param start * @param count * @param after */ View view; private TextChange (View v) { view = v; }//end constructor @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } /** * This method is called to notify you that, within <code>s</code>, * the <code>count</code> characters beginning at <code>start</code> * have just replaced old text that had length <code>before</code>. * It is an error to attempt to make changes to <code>s</code> from * this callback. * * @param s * @param start * @param before * @param count */ @Override public void onTextChanged(CharSequence s, int start, int before, int count) { switch (view.getId()) { case R.id.txtValue1: //insert your TextChangedListener codes here break; case R.id.txtValue2: //insert your TextChangedListener codes here break; }//end switch }//end method onTextChanged }//end inner class TextChange }//end classMainActivity