android on Text Change Listener

J’ai une situation où il y a deux champs. field1 et field2 . Tout ce que je veux faire est vide field1 lorsque field1 est modifié et vice versa. Donc, à la fin, un seul champ contient du contenu.

 field1 = (EditText)findViewById(R.id.field1); field2 = (EditText)findViewById(R.id.field2); field1.addTextChangedListener(new TextWatcher() { 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) { field2.setText(""); } }); field2.addTextChangedListener(new TextWatcher() { 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) { field1.setText(""); } }); 

Cela fonctionne très bien si j’attache addTextChangedListener à field1 seulement, mais quand je le fais pour les deux champs, l’application se bloque. Évidemment parce qu’ils essaient de se changer indéfiniment. Une fois que le field1 change, le field2 field2 est field1 à ce moment le field2 est modifié pour effacer le field1 et ainsi de suite …

Quelqu’un peut-il suggérer une solution?

    Vous pouvez append une vérification pour effacer uniquement lorsque le texte dans le champ n’est pas vide (c.-à-d. Lorsque la longueur est différente de 0).

     field1.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(s.length() != 0) field2.setText(""); } }); field2.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(s.length() != 0) field1.setText(""); } }); 

    Documentation pour TextWatcher ici .

    Veuillez également respecter les conventions de dénomination .

    Je sais que c’est vieux mais quelqu’un pourrait le retrouver un jour.

    J’ai eu un problème similaire où j’appellerais setText sur un EditText et onTextChanged serait appelé quand je ne le voulais pas. Ma première solution a consisté à écrire du code après avoir appelé setText () pour annuler les dommages causés par l’écouteur. Mais ce n’était pas très élégant. Après quelques recherches et tests, j’ai découvert que l’utilisation de getText (). Clear () efface le texte de la même manière que setText (“”), mais comme il ne définit pas le texte, le listener n’est pas appelé. résolu mon problème. J’ai basculé tous mes appels setText (“”) vers getText (). Clear () et je n’avais plus besoin des bandages, alors cela résoudra peut-être aussi votre problème.

    Essaye ça:

     Field1 = (EditText)findViewById(R.id.field1); Field2 = (EditText)findViewById(R.id.field2); Field1.addTextChangedListener(new TextWatcher() { 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) { Field2.getText().clear(); } }); Field2.addTextChangedListener(new TextWatcher() { 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) { Field1.getText().clear(); } }); 

    Un peu en retard, mais voici une solution réutilisable:

     /** * An extension of TextWatcher which stops further callbacks being called as * a result of a change happening within the callbacks themselves. */ public abstract class EditableTextWatcher implements TextWatcher { private boolean editing; @Override public final void beforeTextChanged(CharSequence s, int start, int count, int after) { if (editing) return; editing = true; try { beforeTextChange(s, start, count, after); } finally { editing = false; } } protected abstract void beforeTextChange(CharSequence s, int start, int count, int after); @Override public final void onTextChanged(CharSequence s, int start, int before, int count) { if (editing) return; editing = true; try { onTextChange(s, start, before, count); } finally { editing = false; } } protected abstract void onTextChange(CharSequence s, int start, int before, int count); @Override public final void afterTextChanged(Editable s) { if (editing) return; editing = true; try { afterTextChange(s); } finally { editing = false; } } public boolean isEditing() { return editing; } protected abstract void afterTextChange(Editable s); } 

    Donc, lorsque ce qui précède est utilisé, tous les setText() qui se produisent dans TextWatcher n’entraîneront plus l’appel de TextWatcher:

     /** * A setText() call in any of the callbacks below will not result in TextWatcher being * called again. */ public class MyTextWatcher extends EditableTextWatcher { @Override protected void beforeTextChange(CharSequence s, int start, int count, int after) { } @Override protected void onTextChange(CharSequence s, int start, int before, int count) { } @Override protected void afterTextChange(Editable s) { } } 

    check Ssortingng avant de définir un autre EditText pour le vider. si Field1 est vide alors pourquoi avoir besoin de changer à nouveau à (“”)? afin que vous puissiez vérifier la taille de votre chaîne avec s.lenght () ou toute autre solution

    Une autre façon de vérifier la longueur de la chaîne est la suivante:

     Ssortingng sUsername = Field1.getText().toSsortingng(); if (!sUsername.matches("")) { // do your job } 

    J’ai également rencontré le même problème et continue à obtenir des exceptions complètes de la stack, et je viens avec la solution suivante.

      edt_amnt_sent.addTextChangedListener(new TextWatcher() { @Override public void afterTextChanged(Editable s) { if (skipOnChange) return; skipOnChange = true; try { //method } } catch (NumberFormatException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { skipOnChange = false; } } }); edt_amnt_receive.addTextChangedListener(new TextWatcher() { @Override public void afterTextChanged(Editable s) { if (skipOnChange) return; skipOnChange = true; try { //method } catch (NumberFormatException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { skipOnChange = false; } } }); 

    déclaré initialement booléen skipOnChange = false;

    Vous pouvez également utiliser la méthode hasFocus ():

     public void onTextChanged(CharSequence s, int start, int before, int count) { if (Field2.hasfocus()){ Field1.setText(""); } } 

    J’ai testé cela pour un travail collégial sur lequel je travaillais pour convertir les échelles de température au fur et à mesure que l’utilisateur les saisissait. Travaillé parfaitement et c’est beaucoup plus simple.

    Si vous utilisez Kotlin pour le développement Android, vous pouvez append un écouteur de changement de texte à l’aide de ce code:

     myTextField.addTextChangedListener(object : TextWatcher{ override fun afterTextChanged(s: Editable?) {} override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {} })