TextWatcher para más de un EditText

Quiero implementar la interfaz TextWatcher para más de un campo EditText . Actualmente estoy usando:

 text1.addTextChangedListener(this); text2.addTextChangedListener(this); 

luego anulando los métodos en mi Actividad:

 public void afterTextChanged(Editable s) {} public void beforeTextChanged(CharSequence s, int start, int count, int after) {} public void onTextChanged(CharSequence s, int start, int before, int count) { // do some operation on text of text1 field // do some operation on text of text2 field } 

Sin embargo, esto está funcionando bien, pero estoy buscando otras formas para que pueda identificar explícitamente en qué campo SoftKeyboard se está enfocando SoftKeyboard actualmente.

La solución sugerida en la respuesta de @Sebastian Roth no es una instancia de TextWatcher para algunos EditTexts . Es una clase y n instancias de esa clase para n EditTexts .

Cada EditText tiene su propio Spannable. TextWatcher eventos de TextWatcher tienen este parámetro como Spannable. Reviso su hashCode (identificador único de cada objeto). myEditText1.getText () devuelve ese Spannable. Entonces, si myEditText1.getText().hashCode() es igual a s.hashCode() significa que s pertenece a myEditText1

Entonces, si quiere tener una instancia de TextWatcher para algunos EditTexts , debe usar esto:

 private TextWatcher generalTextWatcher = new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { if (myEditText1.getText().hashCode() == s.hashCode()) { myEditText1_onTextChanged(s, start, before, count); } else if (myEditText2.getText().hashCode() == s.hashCode()) { myEditText2_onTextChanged(s, start, before, count); } } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { if (myEditText1.getText().hashCode() == s.hashCode()) { myEditText1_beforeTextChanged(s, start, count, after); } else if (myEditText2.getText().hashCode() == s.hashCode()) { myEditText2_beforeTextChanged(s, start, count, after); } } @Override public void afterTextChanged(Editable s) { if (myEditText1.getText().hashCode() == s.hashCode()) { myEditText1_afterTextChanged(s); } else if (myEditText2.getText().hashCode() == s.hashCode()) { myEditText2_afterTextChanged(s); } } }; 

y

 myEditText1.addTextChangedListener(generalTextWatcher); myEditText2.addTextChangedListener(generalTextWatcher); 

Lo haría así:

 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); EditText e = new EditText(this); e.addTextChangedListener(new CustomTextWatcher(e)); } private class CustomTextWatcher implements TextWatcher { private EditText mEditText; public CustomTextWatcher(EditText e) { mEditText = e; } public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void onTextChanged(CharSequence s, int start, int before, int count) { } public void afterTextChanged(Editable s) { } } 

usando la idea de “CustomTextWatcher”, lo hice

1) Crated una nueva interfaz TextWatcherListener:

 public interface TextWatcherExtendedListener extends NoCopySpan { public void afterTextChanged(View v, Editable s); public void onTextChanged(View v, CharSequence s, int start, int before, int count); public void beforeTextChanged(View v, CharSequence s, int start, int count, int after); } 

2) Creado y usado EditTextExtended en lugar de EditText (en mi caso):

 public class EditTextExtended extends EditText { private TextWatcherExtendedListener mListeners = null; public EditTextExtended(Context context) { super(context); } public EditTextExtended(Context context, AttributeSet attrs) { super(context, attrs); } public EditTextExtended(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public void addTextChangedListener(TextWatcherExtendedListener watcher) { if (mListeners == null) { mListeners = watcher; } } public void removeTextChangedListener(TextWatcherExtendedListener watcher) { if (mListeners != null) { mListeners = null; } } void sendBeforeTextChanged(CharSequence text, int start, int before, int after) { if (mListeners != null) { mListeners.beforeTextChanged(this, text, start, before, after); } } void sendOnTextChanged(CharSequence text, int start, int before,int after) { if (mListeners != null) { mListeners.onTextChanged(this, text, start, before, after); } } void sendAfterTextChanged(Editable text) { if (mListeners != null) { mListeners.afterTextChanged(this, text); } } } 

3) Entonces, donde necesita escribir este código:

 myEditTextExtended.addTextChangedListener(this) //Let implement TextWatcherExtendedListener methods 

4) usarlos:

 @Override public void onTextChanged(View v, CharSequence s, int start, int before, int count) { //Tested and works //do your stuff } @Override public void beforeTextChanged(View v, CharSequence s, int start, int count, int after) { //not yet tested but it should work } @Override public void afterTextChanged(View v, Editable s) { //not yet tested but it should work } 

Bien, déjame saber qué piensas.

–EDITAR–

Si desea usar solo editables después de la comparación de texto:

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

Yo uso esta solución:

  • Agregue el método que devuelve el oyente:

     private TextWatcher getTextWatcher(final EditText editText) { return 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) { // do what you want with your EditText editText.setText("blabla"); } @Override public void afterTextChanged(Editable editable) { } }; } 
  • Agregar oyente a múltiples EditText, también puede pasar otros parámetros:

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

Una forma más de hacerlo es agregar OnClickListener a EditText y establecer una variable global como se indica a continuación

 EditText etCurrentEditor;//Global variable @Override public void onClick(View v) { // TODO Auto-generated method stub if(v instanceof EditText){ etCurrentEditor=(EditText)v; } } 

Utilice este etCurrentEditor como referencia del EditText editado actualmente

 @Override public void afterTextChanged(Editable editable) { // TODO Auto-generated method stub switch (etCurrentEditor.getId()) { case R.id.EDITTEXTID: break; default: break; } } 

Sí, podría usar varias instancias de un TextWatcher personalizado que almacene TextView . ( TextView es en realidad la clase que tiene addTextChangedListener ).

Similar a la solución hashCode anterior, puedes simplemente verificar si getText()==s . En lugar de almacenar todos sus controles o findViewById varias veces, puede escanear el árbol de contenido usted mismo una vez para el control que tiene CharSequence .

 public TextView findTextView(View v, CharSequence s) { TextView tv; ViewGroup vg; int i, n; if (v instanceof TextView) { tv = (TextView) v; if (tv.getText()==s) return(tv); } else if (v instanceof ViewGroup) { vg = (ViewGroup) v; n = vg.getChildCount(); for(i=0;i 

Por supuesto, también podría usar findTextView dentro de beforeTextChanged y onTextChanged .

Una clase global para todas las actividades.

CustomTextWatcher.java

 package org.logicbridge.freshclub.customizedItems; import android.content.Context; import android.text.Editable; import android.text.TextWatcher; public class CustomTextWatcher implements TextWatcher { private EditText mEditText; Context context; public CustomTextWatcher(EditText e, Context context) { mEditText = e; this.context = context; } public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void onTextChanged(CharSequence s, int start, int before, int count) { } public void afterTextChanged(Editable s) { } } 

Lo implementé como:

 edittext1.addTextChangedListener(this); edittext2.addTextChangedListener(this); edittext3.addTextChangedListener(this); 

y:

 @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { if(edittext1.hasFocus()){ //text changed for edittext1 }else if(edittext2.hasFocus()){ //text changed for edittext2 }else { //text changed for edittext3 } } @Override public void afterTextChanged(Editable editable) { } 

Después de probar varias formas de lograr esto, encuentro la manera correcta usando EditText.isFocused() para distinguir uno de otro. Por ejemplo:

  private class OnTextChangedListener implements 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) { if (edtName.isFocused()) { //do something } else if (edtEmail.isFocused()) { //do something } else if (edtContent.isFocused()) { //do something } } } 

Siempre puede definir TextWatcher como un parámetro para addTextChangedListener método addTextChangedListener esta forma puede tener múltiples definiciones para cada texto de edición.

simplemente compare los códigos hash de edittext y string al usar el método hashCode ()

 @Override public void afterTextChanged(Editable s) { if (editext.getText().hashCode() == s.hashCode()){ type1Total(type1List); } } 

Esto es lo que hice …

 private TextWatcher textWatcher = 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) { if (editText1.getText().length() > 0 && editText2.getText().length() > 0 && editText3.getText().length() > 0) { button.setEnabled(true); } else { button.setEnabled(false); } } @Override public void afterTextChanged(Editable s) { } 

Luego, simplemente agregué el TextWatcher a cada EditText en el método onCreate y también mantuve el botón setEnabled (false) por defecto aquí.

 button.setEnabled(false); editText1.addTextChangedListener(textWatcher); editText2.addTextChangedListener(textWatcher); editText3.addTextChangedListener(textWatcher);