TextWatcher événements déclenchés plusieurs fois

J'ai un problème ennuyeux avec TextWatcher. j'ai cherché sur le web, mais je n'ai rien trouvé. reconnaissant si quelqu'un pouvait m'aider.

pour une raison quelconque, les appels aux événements TextWatcher après un changement de texte sont erratiques. parfois ils sont déclenchés une fois (comme ils devraient l'être), parfois deux fois, et parfois trois fois. n'ai aucune idée de pourquoi, le tout est très simple. parfois aussi le modifiable le paramètre on afterTextChanged() renvoie les valeurs vides dans toString () et length ().

code ci-dessous:

    private TextWatcher mSearchAddressTextChangeListener = new TextWatcher() {
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) { }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) { }

        @Override
        public void afterTextChanged(Editable searchedAddress) {
           System.out.println("called multiple times.");   
        }
    };

à l'intérieur afterTextChanged() (et le AsyncTask ) je ne suis pas le fait de modifier le texte ou le EditText .

j'ai vu la question posée dans les événements de TextWatcher sont appelés deux fois , mais im ayant les événements déclenchés plus (ou moins) que deux fois.

de toute façon, j'apprécie toute aide.

EDIT: j'ai supprimé le contenu de afterTextChanged() car ce problème se produit même sans mon code. ce qui m'amène à croire que c'est un bug. Le bogue se produit lorsqu'un caractère' space 'est entré juste après un caractère régulier (les gestionnaires d'événements sont déclenchés deux fois) ou lorsqu'un caractère' space ' après un caractère régulier est supprimé (backspace. les gestionnaires d'événements sont déclenchés 3 fois). l'aide sera toujours apprécié.

27
demandé sur Community 2013-07-09 00:27:22

5 réponses

j'ai eu le même genre de problème, quand j'ai pressé backspace avec curseur à la fin d'un texte continu, afterTextChange a été appelé 3 fois: - La première fois avec la bonne valeur - La deuxième fois avec une valeur précise - La troisième fois avec la valeur correcte à nouveau

après avoir cherché beaucoup sur le web, j'ai essayé de changer mon entrée de texte en

android:inputType="textNoSuggestions"

ne me demandez pas pourquoi, mais cela a fonctionné, après que TeX-modified est maintenant appelé seulement lorsque.

46
répondu Nico 2013-10-10 14:29:57

selon les pages du développeur pour TextWatcher , si un changement est fait au Editable dans TextWatcher , il déclenchera d'autres appels à tous les TextWatchers lié à celui Editable . Il est clair que votre code ne déclenche pas ce comportement.

cependant, il est tout à fait possible que si, pour une raison quelconque , le système a un TextWatcher sur le Editable , la situation que vous décrivez peut se produire. "Pourquoi", je t'entends pleurer, "si cela arrive?"

tout d'abord, la défense classique: il n'y a aucune raison pour que cela n'arrive pas et, à strictement parler, le code app doit être écrit pour être résistant à lui.

deuxièmement, je ne peux pas le prouver, mais je pourrais bien imaginer que le code qui gère la disposition du texte affiché dans un EditText utilise un TextWatcher pour gérer la mise à jour de l'affichage du texte sur l'écran. Ce code peut insérer des codes de contrôle (qui ne sont pas affichés) dans Editable pour assurer une bonne rupture de ligne et ainsi de suite. Il peut même faire le tour d'une boucle à quelques reprises pour l'obtenir correctement, et vous pourriez seulement obtenir votre premier appel après qu'il a fait tout le sien ...

EDIT

selon le commentaire de @Learn, l'appel D'un TextWatcher serait normal pour des choses comme autocorrect.

7
répondu Neil Townsend 2013-10-12 09:29:23
boolean isOnTextChanged = false;

@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
    isOnTextChanged = true;
}

@Override
public void afterTextChanged(Editable quantity) {
    if (isOnTextChanged) {
        isOnTextChanged = false;
       //dosomething
    }
3
répondu velraj 2017-04-07 09:57:33

u peut utiliser un contrôle booléen, comme:

    inputBoxNumberEt.addTextChangedListener(new TextWatcher() {

        boolean ignoreChange = false;

        @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 (!ignoreChange) {
              ///Do your checks                    
                ignoreChange = true;
                inputBoxNumberEt.setText(string);
                inputBoxNumberEt.setSelection(inputBoxNumberEt.getText().length());
                ignoreChange = false;
            }
        }
    });
1
répondu M. Usman Khan 2016-03-03 14:16:53