Cambiar texto en Android en el cambio de texto causa error de desbordamiento
Quiero crear una aplicación que puede transformar el texto que el usuario ingresa en un widget EditText
en tiempo real, y he añadido un TextWatcher
para permitirme hacer cosas en el cambio de texto, pero está causando un error de desbordamiento porque estoy básicamente creando Un bucle sin fin ( onTextChange -> code to change text -> onTextChange -> etc...
).
¿Alguien tiene una idea sobre cómo solucionar este problema?
Aquí está un ejemplo
private boolean isEditable = true; private EditText text; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); text = (EditText) findViewById(R.id.editText1); text.addTextChangedListener(new TextWatcher() { @Override public void afterTextChanged(Editable s) { } @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 (isEditable) { isEditable = false; styleText(s.toString()); } else { isEditable = true; } } }); } private void styleText(String completeText) { text.setText(completeText + " test"); }
Y mientras que lo anterior realmente parece estar funcionando, no puedo conseguir que funcione con Html.fromHtml();
, Que es lo que voy a utilizar.
EDITADO OTRA VEZ
public class Main extends Activity implements TextWatcher { private EditText text; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); text = (EditText) findViewById(R.id.editText1); text.addTextChangedListener(this); } @Override public void afterTextChanged(Editable s) { text.removeTextChangedListener(this); } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { text.addTextChangedListener(this); } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { text.removeTextChangedListener(this); text.setText("Test!"); } }
Se está lanzando una StackOverflowException
en la línea 37, que es " text.setText("Test!");
"
EDIT: Y funciona, sin excepción se lanza:
txtwt = new TextWatcher(){ @Override public void afterTextChanged(Editable s) { Log.i("REACHES AFTER", "YES"); } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { Log.i("REACHES BEFORE", "YES"); } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { text.removeTextChangedListener(txtwt);//after this line you do the editing code text.setText("TEST"); Log.i("REACHES ON", "YES"); text.addTextChangedListener(txtwt); // you register again for listener callbacks }}; text = (EditText) findViewById(R.id.editText1); text.addTextChangedListener(txtwt);
Esta es la prueba de Logcat, cuando empujé dramáticamente las claves:
08-28 19:53:21.265: INFO/REACHES BEFORE(492): YES 08-28 19:53:21.276: INFO/REACHES ON(492): YES 08-28 19:53:21.276: INFO/REACHES AFTER(492): YES 08-28 19:53:21.296: INFO/REACHES BEFORE(492): YES 08-28 19:53:21.305: INFO/REACHES ON(492): YES 08-28 19:53:21.305: INFO/REACHES AFTER(492): YES 08-28 19:53:21.745: INFO/REACHES BEFORE(492): YES 08-28 19:53:21.755: INFO/REACHES ON(492): YES 08-28 19:53:21.755: INFO/REACHES AFTER(492): YES 08-28 19:53:21.775: INFO/REACHES BEFORE(492): YES 08-28 19:53:21.785: INFO/REACHES ON(492): YES 08-28 19:53:21.785: INFO/REACHES AFTER(492): YES 08-28 19:53:22.698: INFO/REACHES BEFORE(492): YES 08-28 19:53:22.705: INFO/REACHES ON(492): YES 08-28 19:53:22.705: INFO/REACHES AFTER(492): YES 08-28 19:53:23.855: INFO/REACHES BEFORE(492): YES 08-28 19:53:23.865: INFO/REACHES ON(492): YES 08-28 19:53:23.865: INFO/REACHES AFTER(492): YES 08-28 19:53:24.385: INFO/REACHES BEFORE(492): YES 08-28 19:53:24.395: INFO/REACHES ON(492): YES 08-28 19:53:24.395: INFO/REACHES AFTER(492): YES 08-28 19:53:24.485: INFO/REACHES BEFORE(492): YES 08-28 19:53:24.485: INFO/REACHES ON(492): YES 08-28 19:53:24.485: INFO/REACHES AFTER(492): YES 08-28 19:53:24.515: INFO/REACHES BEFORE(492): YES 08-28 19:53:24.525: INFO/REACHES ON(492): YES 08-28 19:53:24.525: INFO/REACHES AFTER(492): YES 08-28 19:53:24.625: INFO/REACHES BEFORE(492): YES 08-28 19:53:24.635: INFO/REACHES ON(492): YES 08-28 19:53:24.635: INFO/REACHES AFTER(492): YES 08-28 19:53:24.654: INFO/REACHES BEFORE(492): YES 08-28 19:53:24.665: INFO/REACHES ON(492): YES 08-28 19:53:24.665: INFO/REACHES AFTER(492): YES
private String originalValue; void onTextChanged(CharSequence text, int start, int before, int after) { if (text.toString().equals(originalValue)) { // do nothing } else { //change your text originalValue = text.toString(); } }
Editado:
public void onTextChanged(CharSequence s, int start, int before, int count) { String currentText = s.toString(); if (currentText.equals(originalValue)) { //the originalValue must be defined outside of the Watcher originalValue = styleText(currentText); // text.setText(originalValue); //if styleText doesn't do this } else { return; } }