studio - propiedades edittext android
¿Detecta si el contenido de EditText fue cambiado por el usuario o programáticamente? (4)
Esto se solucionó hace mucho tiempo, pero para cualquiera que encuentra su camino aquí buscando una respuesta, esto es lo que hice:
Terminé configurando Tag of the EditText en algún valor arbitrario justo antes de comenzar a cambiarlo programáticamente, y cambiar el valor, y luego reiniciar Tag a null. Luego, en mi método TextWatcher.afterTextChanged () compruebo si la etiqueta es nula o no para determinar si fue el usuario o el programa que cambió el valor. ¡Funciona de maravilla!
Algo como esto:
edit.setTag( "arbitrary value" );
edit.setText( "My Text Value" );
edit.setTag(null);
y entonces
public void afterTextChanged(Editable s) {
if( view.getTag() == null )
// Value changed by user
else
// Value changed by program
}
Necesitaría una forma de detectar si EditText ha sido modificado por el usuario al escribir algo o por la aplicación cambiando el texto mediante programación. ¿Alguna forma estándar de hacer esto? Supongo que siempre podría hacer algo como abrir y cerrar el TextWatcher antes de setText()
y volver a configurarlo después, pero tiene que haber una forma mejor de hacerlo ... ¿no?
Intenté comprobar si EditText está enfocado en el TextWatcher, pero eso fue de poca ayuda ya que EditTexts se enfoca "semi-aleatoriamente" de todos modos al desplazarse ...
Fondo
Tengo un ListView con EditTexts en cada elemento de lista. Resolví el problema básico de almacenar los valores de EditTexts para su reutilización cuando el usuario se desplaza.
También tengo un TextWatcher que resume los valores en todos los EditTexts y muestra la suma cuando el usuario edita el contenido de cualquiera de los EditTexts.
El problema es que cuando estoy desplazando la lista y mi adaptador personalizado vuelve a entrar en los valores almacenados en EditTexts en bindView()
, también desencadena el método afterTextChanged()
bindView()
, lo que provoca que el desplazamiento se afterTextChanged()
debido a la función afterTextChanged()
se dispara.
La respuesta aceptada es perfectamente válida, pero tengo otro enfoque;
@Override
public void onTextChanged(CharSequence charSequence,
int start, int before, int count) {
boolean userChange = Math.abs(count - before) == 1;
if (userChange) {
}
}
Funciona comprobando si el cambio fue de un solo carácter. Esta no es una solución infalible ya que las operaciones de copiado y pegado pueden pasar inadvertidas, y los cambios que no sean del usuario de un solo carácter también se perderán. Dependiendo de su caso de uso, esta podría ser una solución viable.
Puedes hacer esto agregando:
private String current = "";
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(!s.toString().equals(current)){
[your_edittext].removeTextChangedListener(this);
//Format your string here...
current = formatted;
[your_edittext].setText(formatted);
[your_edittext].setSelection(formatted.length());
[your_edittext].addTextChangedListener(this);
}
Una cosa que me ayudó es tener el campo boolean canListenInput. Úselo dentro del observador.
email.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
if (canListenInput) {
emailChanged = true;
}
}
});
Límpielo antes de cambiar el texto mediante programación. Configúrelo dentro de la restauración onAttachedToWindow, (después del estado):
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
canListenInput = true;
}