edittext - textwatcher android
TextWatcher para más de un EditText (13)
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
}
}
}
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.
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);
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) {
}
}
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) {
}
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<n;i++)
{
tv = findTextView(vg.getChildAt(i), s);
if (tv!=null) return(tv);
}
}
return(null);
}
public void afterTextChanged(Editable s)
{
TextView tv=findTextView(findViewById(android.R.id.content), s);
if (tv==null) return;
switch(tv.getId())
{
case R.id.path:
break;
case R.id.title:
break;
}
}
Por supuesto, también podría usar findTextView
dentro de beforeTextChanged
y onTextChanged
.
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.
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) {
}
}
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;
}
}
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));
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);
}
}
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
}
}