studio - textview watcher in android
Diferencias entre TextTatcher enTextChanged, beforeTextChanged y afterTextChanged (5)
En mi proyecto de Android tuve que agregar un TextChangedListener (TextWatcher) a una vista de edición de texto. Y hay tres partes en ella.
onTextChanged
-
beforeTextChanged
-
afterTextChanged
¿Cuáles son los diferentes de estos tres? He tenido que implementar una búsqueda de una tabla en el administrador de claves y, en mi caso, estos tres parecen iguales. También funcionaron igual. Cuando ingreso una parte del nombre de un producto, la tabla se vuelve a dibujar y solo esos productos contienen el texto ingresado. Pero utilicé la parte afterTextChanged
. Mi codigo es
EditProduct.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
// TODO Auto-generated method stub
// System.out.println("onTextChanged"+s);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
// System.out.println("beforeTextChanged"+s);
}
@Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
// System.out.println("afterTextChanged"+s);
String new_prx = s.toString();
System.out.println(s);
mini_productList = new ArrayList<Product>();
// mini_productList
int count = 0;
if (new_prx.equals("")) {
loadtableProducts(productList);
} else {
for (int i = 0; i < productList.size(); i++) {
if (productList.get(i).getDescription().toString()
.substring(0, (new_prx.length()))
.equalsIgnoreCase(new_prx)) {
mini_productList.add(productList.get(i));
count++;
}
}
loadtableProducts(mini_productList);
}
}
});
Entonces, ¿alguien puede darme una explicación sobre estos tres?
afterTextChanged (Editable s): este método se invoca cuando se modifica el texto. Debido a que cualquier cambio que realice hará que este método se vuelva a llamar de forma recursiva, debe estar atento a la realización de las operaciones aquí, de lo contrario, podría dar lugar a un bucle infinito.
beforeTextChanged (CharSequence s, int start, int count, int after): se llama a este método para notificarle que, dentro de s, los caracteres de conteo que comienzan al inicio están a punto de ser reemplazados por un nuevo texto con una longitud posterior. Es un error intentar realizar cambios en s desde esta devolución de llamada.
onTextChanged (CharSequence s, int start, int before, int count): este método se llama para notificarle que, dentro de s, los caracteres de conteo que comienzan en el inicio acaban de reemplazar el texto antiguo que tenía la longitud anterior. Es un error intentar realizar cambios en s desde esta devolución de llamada.
abstract void afterTextChanged(Editable s)
Se llama a este método para notificarle que, en algún lugar dentro de s, el texto ha sido cambiado.
abstract void beforeTextChanged(CharSequence s, int start, int count, int after)
Se llama a este método para notificarle que, dentro de s, los caracteres de conteo que comienzan en el inicio están a punto de ser reemplazados por un nuevo texto con una longitud posterior.
abstract void onTextChanged(CharSequence s, int start, int before, int count)
Se llama a este método para notificarle que, dentro de s, los caracteres de conteo que comienzan en el inicio acaban de reemplazar el texto antiguo que tenía la longitud anterior.
Puedes aprender más here .
Android TextChangedListener
es un tipo de activador que se llama en el cambio de texto de un campo de entrada.
TextChangedListener
tiene tres eventos.
1.beforeTextChanged: Esto significa que los caracteres están a punto de ser reemplazados por algún texto nuevo. El texto no es editable. Este evento se utiliza cuando necesita ver el texto antiguo que está a punto de cambiar.
2.onTextChanged: se han realizado cambios, algunos caracteres han sido reemplazados. El texto no es editable. Este evento se usa cuando necesitas ver qué caracteres del texto son nuevos.
3.afterTextChanged: igual que el anterior, excepto que ahora el texto es editable. Este evento se usa cuando necesitas ver y posiblemente editar texto nuevo.
Los parámetros para beforeTextChanged
y onTextChanged
son un poco difíciles de entender al principio. Puede ser útil verlos en un ejemplo. Mira la siguiente demostración unas cuantas veces. Preste atención a los condes.
- El resaltado rojo es el texto antiguo que está a punto de ser reemplazado por el texto verde.
- El resaltado verde es el nuevo texto que acaba de reemplazar el texto rojo.
antesTextChanged
-
start
es el índice de inicio del texto resaltado en rojo (que se va a eliminar) -
count
es la longitud del texto resaltado en rojo (que se va a eliminar) -
after
es la longitud del texto resaltado en verde (que está a punto de agregarse)
enTextChanged
-
start
es el índice de inicio del texto resaltado en verde (que se acaba de agregar).
Esto es lo mismo que elstart
debeforeTextChanged
. -
before
es la longitud del texto resaltado en rojo (que se acaba de eliminar).
Este es el mismo que elcount
debeforeTextChanged
. -
count
es la longitud del texto resaltado en verde (que se acaba de agregar).
Esto es lo mismo queafter
debeforeTextChanged
.
afterTextChanged
-
editable
es el texto editable del EditText. Puedes cambiarlo aquí. Si lo hace, volverá a activar todos los eventosTextWatcher
. - No se le da ninguna información sobre lo que se cambió. Si desea saber, puede establecer un intervalo en
onTextChanged
y, a continuación, buscar el intervalo aquí.
¿Cuándo usar cuál?
Si desea observar los cambios realizados, use beforeTextChanged()
o onTextChanged()
. Sin embargo, no está permitido cambiar el texto de CharSequence
en ninguno de estos métodos.
Si desea seguir modificando el texto después de cambiarlo, hágalo en afterTextChanged()
.
Código
Aquí está el código si quieres jugar con él mismo.
MainActivity.java
public class MainActivity extends AppCompatActivity {
final static int RED_COLOR = Color.parseColor("#fb7373");
final static int GREEN_COLOR = Color.parseColor("#40de83");
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EditText editText = findViewById(R.id.editText);
final TextView tvBeforeText = findViewById(R.id.tvBeforeText);
final TextView tvBeforeNumbers = findViewById(R.id.tvBeforeNumbers);
final TextView tvAfterText = findViewById(R.id.tvAfterText);
final TextView tvAfterNumbers = findViewById(R.id.tvAfterNumbers);
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
SpannableString spannableString = new SpannableString(s);
BackgroundColorSpan backgroundSpan = new BackgroundColorSpan(RED_COLOR);
spannableString.setSpan(backgroundSpan, start, start + count, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
tvBeforeText.setText(spannableString);
tvBeforeNumbers.setText("start=" + start + " count=" + count + " after=" + after);
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
SpannableString spannableString = new SpannableString(s);
BackgroundColorSpan backgroundSpan = new BackgroundColorSpan(GREEN_COLOR);
spannableString.setSpan(backgroundSpan, start, start + count, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
tvAfterText.setText(spannableString);
tvAfterNumbers.setText("start=" + start + " before=" + before + " count=" + count);
}
@Override
public void afterTextChanged(Editable s) {
Log.i("TAG", "afterTextChanged: " + s);
}
});
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="5dp">
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="beforeTextChanged" />
<TextView
android:id="@+id/tvBeforeText"
android:textSize="17sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tvBeforeNumbers"
android:textSize="17sp"
android:text="start=0 count=0 after=0"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:layout_marginTop="20dp"
android:text="onTextChanged" />
<TextView
android:id="@+id/tvAfterText"
android:textSize="17sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tvAfterNumbers"
android:textSize="17sp"
android:text="start=0 count=0 after=0"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
onTextChanged
ejecuta durante el cambio de texto.
afterTextChanged
ejecuta inmediatamente después de cambiar el texto.
beforeTextChanged
ejecuta el instante antes de que se cambie el texto.
Dependiendo de cuándo desea asignar variables o hacer cosas, es posible que desee ejecutar el código un instante antes del cambio, o un instante después.
Aquí hay un ejemplo de esto:
String afterTextChanged = "";
String beforeTextChanged = "";
String onTextChanged = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et = (EditText)findViewById(R.id.editText);
et.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int st, int b, int c)
{
onTextChanged = et.getText().toString();
}
@Override
public void beforeTextChanged(CharSequence s, int st, int c, int a)
{
beforeTextChanged = et.getText().toString();
}
@Override
public void afterTextChanged(Editable s)
{
afterTextChanged = et.getText().toString();
Toast.makeText(Activity.this, "before: " + beforeTextChanged
+ ''/n'' + "on: " + onTextChanged
+ ''/n'' + "after: " + afterTextChanged
,Toast.LENGTH_SHORT).show();
}
});
}
En este caso, digamos que cambió el texto de "h" a "hola", la salida sería:
antes: "h"
en: "hola"
después de "hola"