Cómo eliminar todos los oyentes agregados con addTextChangedListener

Tengo un ListView donde cada fila tiene un control de EditText . Quiero agregar un TextChangedListener a cada fila; Uno que contiene datos adicionales que dice que fila el EditText estaba EditText El problema es que como getView se llama, se agregan múltiples TextWatchers ; Porque el convertView ya tiene un TextWatcher (y otro que apunta a una fila diferente).

 MyTextWatcher watcher = new MyTextWatcher(currentQuestion); EditText text = (EditText)convertView.findViewById(R.id.responseText); text.addTextChangedListener(watcher); 

MyTextWatcher es mi clase que implementa TextWatcher ; Y maneja los eventos de texto. CurrentQuestion me permite saber a qué fila estoy actuando. Cuando escribo en la caja; Se llaman varias instancias de TextWatcher .

¿Hay alguna manera de eliminar el TextWatchers antes de agregar el nuevo? Veo el método removeTextChangedListener , pero eso requiere que un TextWatcher específico sea pasado adentro, y no sé cómo conseguir el puntero al TextWatcher que está ya allí.

No hay manera de hacerlo utilizando la interfaz EditText actual directamente. Veo dos posibles soluciones:

  1. Rediseñe su aplicación para que siempre sepa qué TextWatcher se agrega a la instancia de EditText particular.
  2. Ampliar EditText y añadir la posibilidad de borrar a todos los observadores.

Aquí hay un ejemplo de segundo enfoque: ExtendedEditText :

 public class ExtendedEditText extends EditText { private ArrayList<TextWatcher> mListeners = null; public ExtendedEditText(Context ctx) { super(ctx); } public ExtendedEditText(Context ctx, AttributeSet attrs) { super(ctx, attrs); } public ExtendedEditText(Context ctx, AttributeSet attrs, int defStyle) { super(ctx, attrs, defStyle); } @Override public void addTextChangedListener(TextWatcher watcher) { if (mListeners == null) { mListeners = new ArrayList<TextWatcher>(); } mListeners.add(watcher); super.addTextChangedListener(watcher); } @Override public void removeTextChangedListener(TextWatcher watcher) { if (mListeners != null) { int i = mListeners.indexOf(watcher); if (i >= 0) { mListeners.remove(i); } } super.removeTextChangedListener(watcher); } public void clearTextChangedListeners() { if(mListeners != null) { for(TextWatcher watcher : mListeners) { super.removeTextChangedListener(watcher); } mListeners.clear(); mListeners = null; } } } 

Y aquí es cómo se puede utilizar ExtendedEditText en xml layouts:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ua.inazaruk.HelloWorld.ExtendedEditText android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="header" android:gravity="center" /> </LinearLayout> 

Puede quitar TextWatcher de su EditText. En primer lugar le sugiero que mueva la declaración TextWatcher fuera de la editText.addTextChangedListener (…):

 protected TextWatcher yourTextWatcher = new TextWatcher() { @Override public void afterTextChanged(Editable s) { // your logic here } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { // your logic here } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { // your logic here } }; 

Después de que usted será capaz de configurar TextWather poco más simple:

 editText.addTextChangedListener(yourTextWatcher); 

Que puede quitar TextWatcher como este:

 editText.removeTextChangedListener(yourTextWatcher); 

Y establecer otro si lo desea.

También pasé mucho tiempo encontrando la solución y finalmente terminé resolviendo con la ayuda de etiqueta como abajo. Se quitaría anteriores TextWatcher instancias por obtener referencias de la etiqueta de la convertView. Resuelve perfectamente el problema. En su archivo CustomAdapter, establezca una nueva clase interna como la siguiente:

 private static class ViewHolder { private TextChangedListener textChangedListener; private EditText productQuantity; public EditText getProductQuantity() { return productQuantity; } public TextChangedListener getTextChangedListener() { return textChangedListener; } public void setTextChangedListener(TextChangedListener textChangedListener) { this.textChangedListener = textChangedListener; } } 

A continuación, en su público superpuesto, el método getView (int position, View convertView, ViewGroup parent) implementa la lógica como a continuación:

 @Override public View getView(int position, View convertView, ViewGroup parent) { EditText productQuantity; TextChangedListener textChangedListener; if(convertView==null) { LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE); convertView = mInflater.inflate(R.layout.cart_offer_item, parent, false); productQuantity=(EditText)convertView.findViewById(R.id.productQuantity); addTextChangedListener(viewHolder, position); convertView.setTag(viewHolder); } else { ViewHolder viewHolder=(ViewHolder)convertView.getTag(); productQuantity=viewHolder.getProductQuantity(); removeTextChangedListener(viewHolder); addTextChangedListener(viewHolder, position); } return convertView; } private void removeTextChangedListener(ViewHolder viewHolder) { TextChangedListener textChangedListener=viewHolder.getTextChangedListener(); EditText productQuantity=viewHolder.getProductQuantity(); productQuantity.removeTextChangedListener(textChangedListener); } private void addTextChangedListener(ViewHolder viewHolder, int position) { TextChangedListener textChangedListener=new TextChangedListener(position); EditText productQuantity=viewHolder.getProductQuantity(); productQuantity.addTextChangedListener(textChangedListener); viewHolder.setTextChangedListener(textChangedListener); } 

A continuación, implemente la clase TextWatcher como se muestra a continuación:

 private class TextChangedListener implements TextWatcher { private int position; TextChangedListener(int position) { this.position=position; } @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) { Log.d("check", "text changed in EditText"); } } 

Se eliminaría instancias anteriores de TextWatcher al obtener referencias de la etiqueta del archivo convertView

Guarde el textwatcher actual en el visor y puede encontrar el que desea eliminar.

Tuve el mismo problema con xamarin / C # y escribí para esto una clase para administrar eventos de clic dentro de un ListView donde la vista del elemento será "reciclado":

  public class ViewOnClickEventHandler: Java.Lang.Object { private List<EventHandler> EventList { get; set; } public void SetOnClickEventHandler(View view, EventHandler eventHandler) { if (view.Tag != null) { ViewOnClickEventHandler holder = ((ViewOnClickEventHandler)view.Tag); foreach (EventHandler evH in holder.EventList) view.Click -= evH; for (int i = 0; i < holder.EventList.Count; i++) holder.EventList[i] = null; holder.EventList.Clear(); } EventList = new List<EventHandler>(); EventList.Add(eventHandler); view.Click += eventHandler; view.Tag = this; } } 

Puede utilizarlo en su método ListView BaseAdapter GetItem de esta manera:

  TextView myTextView = convertView.FindViewById<TextView>(Resource.Id.myTextView); ViewOnClickEventHandler onClick = new ViewOnClickEventHandler(); onClick.SetOnClickEventHandler(myTextView, new EventHandler(delegate (object sender, EventArgs e) { // Do whatever you want with the click event })); 

La clase ViewOnClickEventHandler se preocupará por varios eventos en su texto. También puede cambiar la clase para los eventos de intercambio de texto. Es el mismo principio. Espero que esto sea de ayuda.

Bye, nxexo007

Como se puede ver aquí: CodeSearch de TextView no hay manera de eliminar todos los oyentes. La única manera es proporcionar al vigilante que usted utilizó para registrarlo.

Todavía no entiendo por qué hay otros oyentes ya registrados. Sin embargo, puede subclasificar el EditText, anular el addTextChangedListener (..) y en él mantener una copia de todas las referencias añadidas a ti mismo y luego delegar a la implementación de superclase. A continuación, también puede proporcionar un método adicional que elimina todos los oyentes.

Ponte en contacto si necesitas más explicaciones.

Lo que hice para eliminar los observadores de texto es muy simple. He creado una matriz para poner mis textwatchers:

 final TextWatcher[] textWatchers = new TextWatcher[3]; 

Los agregué en:

 final int CURRENT_PIN_CHECK = 0, NEW_PIN = 1, CONFIRM_PIN_CHECK = 2; textWatchers[CURRENT_PIN_CHECK] = returnTextWatcherCheckPIN(CURRENT_PIN_CHECK); textWatchers[NEW_PIN] = returnTextWatcherCheckPIN(NEW_PIN); textWatchers[CONFIRM_PIN_CHECK] = returnTextWatcherCheckPIN(CONFIRM_PIN_CHECK); 

Mi método returnTextWatcherCheckPIN crea una instancia de textWatcher con un comprobador diferente (switchMethod para comprobar los cuatro editTexts) en afterTextChanged.

Entonces cada vez que quito un observador del texto apenas he referido el uno de la matriz:

 etPin4.removeTextChangedListener(textWatchers[CURRENT_PIN_CHECK]); 

Compruebe el tamaño de los oyentes del editText en depuración:

Introduzca aquí la descripción de la imagen

¡Se ha eliminado! Eso resolvió mi problema!

  • Formatear el número de teléfono de EditText como tipos de usuario
  • Eventos de TextWatcher se están llamando dos veces
  • Detectar retroceso en TextWatcher
  • Clase interna dentro de una interfaz que implementa la misma interfaz, ¿qué estamos logrando con esto?
  • Android TextWatcher.afterTextChanged vs TextWatcher.onTextChanged
  • Cómo dar formato a la entrada de EditText al escribir con separadores de miles (,) en Android?
  • Reemplazar el carácter dentro de TextWatcher en android
  • Android edittext onchange escucha
  • Los caracteres de cuenta con TextWatcher fallan en HTC longpress
  • AutocompleteTextView dinámico con ArrayAdapter y TextWatcher
  • Android utiliza el observador de texto para evitar escribir caracteres especiales
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.