TextWatcher-gebeurtenissen worden meerdere keren geactiveerd

Ik heb een vervelend probleem met TextWatcher. ik heb op internet gezocht maar kon niets vinden. stel het op prijs als iemand me kan helpen.

Om de een of andere reden zijn de oproepen naar de TextWatcher-gebeurtenissen na één tekstwijzigingonregelmatig. soms worden ze één keer geactiveerd (zoals ze zouden moeten zijn), soms twee keer en soms 3 keer. heb geen idee waarom, het hele ding is heel eenvoudig. soms retourneert de bewerkbare parameter op afterTextChanged() lege waarden in toString() en length().

code staat hieronder:

   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.");   
        }
    };

in afterTextChanged()(en de AsyncTask) breng ik geen wijzigingen aan in de tekst of de EditText-weergave.

ik zag de vraag gesteld in Evenementen van TextWatcher worden twee keer genoemd, maar ik heb de gebeurtenissen meer (of minder) dan twee keer geactiveerd.

hoe dan ook, stel alle hulp op prijs.

BEWERK:ik heb de inhoud van afterTextChanged() verwijderd omdat dit probleem zich zelfs zonder mijn code voordoet. wat me doet geloven dat dit een bug is. De bug doet zich voor wanneer een ‘spatie’-teken wordt ingevoerd direct na een gewone teken (event-handlers worden twee keer geactiveerd) of wanneer een ‘spatie’-teken na een gewone teken wordt verwijderd (backspace. gebeurtenis-handlers worden 3 keer geactiveerd). hulp wordt nog steeds op prijs gesteld.


Antwoord 1, autoriteit 100%

Ik had hetzelfde soort probleem, toen ik op backspace drukte met de cursor aan het einde van een doorlopende tekst, werd afterTextChange 3 keer aangeroepen:
– De eerste keer met de juiste s-waarde
– De tweede keer met een duidelijke waarde
– De derde keer met de juiste waarde weer

Na veel zoeken op internet, heb ik geprobeerd mijn EditText inputType te veranderen in

android:inputType="textNoSuggestions"

Vraag me niet waarom, maar het werkte, afterTextChanged wordt nu maar één keer aangeroepen.


Antwoord 2, autoriteit 15%

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
    }

Antwoord 3, autoriteit 14%

Volgens de ontwikkelaarspagina’s voor TextWatcher, als er een wijziging is gemaakt naar de Editablebinnen TextWatcher, zal het verdere oproepen activeren naar alle TextWatchersdie aan die Editablezijn gekoppeld. Het is duidelijk dat uw code dit gedrag niet triggert.

Het is echter heel goed mogelijk dat als, om welke reden dan ook, het systeem een ​​TextWatcherop de Editableheeft, de situatie die u beschrijft zich kan voordoen. “Waarom”, hoor ik je huilen, “moet dit gebeuren?”

Ten eerste de klassieke verdediging: er is geen reden om het niet te laten gebeuren en strikt genomen moet app-code zo worden geschreven dat deze er bestand tegen is.

Ten tweede kan ik het niet bewijzen, maar ik kan me goed voorstellen dat de code die de lay-out van de weergegeven tekst in een EditTextafhandelt, een TextWatchergebruikt om het bijwerken af ​​te handelen de weergave van de tekst op het scherm. Deze code kan controlecodes (die u niet ziet) invoegen in de Editableom te zorgen voor goede regeleinden, enzovoort. Het kan zelfs een paar keer rond een lus gaan om het goed te doen, en je krijgt misschien pas je eerste oproep nadat het al zijn …

BEWERKEN

Volgens de opmerking van @Learn OpenGL ES zou het aanroepen van een TextWatcher normaal zijn voor zaken als autocorrectie.


Antwoord 4, autoriteit 7%

Ik heb alle antwoorden op deze vraag geprobeerd, geen van alle werkte voor mij. Maar na wat zoeken vond ik ditbericht. Het gebruik van de RxJava om de debounce te maken werkte goed voor mij. Hier komt mijn definitieve oplossing:

RxJava-afhankelijkheden toevoegen aan het Gradle-bestand:

compile 'io.reactivex:rxandroid:1.0.1'
compile 'io.reactivex:rxjava:1.0.14'
compile 'com.artemzin.rxjava:proguard-rules:1.0.14.2'

Implementeer je onderwerp:

PublishSubject<String> yourSubject = PublishSubject.create();
    yourSubject .debounce(100, TimeUnit.MILLISECONDS)
            .onBackpressureLatest()
            .subscribe(s -> {
                //Implements anything you want
            });

Gebruik je onderwerp in je TextWatcher:

TextWatcher myTextWatcher = 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) {
        yourSubject.onNext(s.toString()); //apply here your subject
    }
    @Override
    public void afterTextChanged(Editable s) {
    }
};

Voeg de TextWatcher toe aan de EditText-listener:

my_edit_text.addTextChangedListener(myTextWatcher);

Antwoord 5, autoriteit 5%

u kunt een booleaanse controle gebruiken, zoals:

   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;
            }
        }
    });

Antwoord 6, autoriteit 3%

Voor mij werkte de onderstaande code. Houd er rekening mee dat de booleaanse waarde is gewijzigd na de if-voorwaardelus in de afterTextChanged-methode

       edittext.addTextChangedListener(new TextWatcher() 
        {
            boolean considerChange = false;
            public void beforeTextChanged(CharSequence cs, int start, int count, int after) {}
            public void onTextChanged(CharSequence cs, int start, int before, int count) {}
            public void afterTextChanged(Editable editable) 
            {
                if (considerChange) 
                { 
                    // your code here
                }
                considerChange = !considerChange; //see that boolean value is being changed after if loop
            }
        });

Other episodes