J'ai un EditText
champ avec un observateur de texte client dessus. Dans un morceau de code, j'ai besoin de changer la valeur du EditText que j'utilise .setText("whatever")
.
Le problème est que dès que je fais ce changement, la afterTextChanged
méthode est appelée, ce qui crée une boucle infinie. Comment puis-je changer le texte sans qu'il ne déclenche afterTextChanged?
J'ai besoin du texte dans la méthode afterTextChanged, alors ne suggérez pas de supprimer le fichier TextWatcher
.
java
android
event-handling
infinite-loop
user1143767
la source
la source
Réponse courte
Vous pouvez vérifier quelle vue a actuellement le focus pour faire la distinction entre les événements déclenchés par l'utilisateur et le programme.
Longue réponse
En complément de la réponse courte: dans le cas où a
myEditText
déjà le focus lorsque vous modifiez par programme le texte que vous devez appelerclearFocus()
, alors vous appelezsetText(...)
et après vous re-demandez le focus. Ce serait une bonne idée de mettre cela dans une fonction d'utilité:Pour Kotlin:
Puisque Kotlin prend en charge les fonctions d'extension, votre fonction utilitaire pourrait ressembler à ceci:
la source
getActivity().getCurrentFocus()
and kotlinactivity?.currentFocus
hasFocus()
directement sur leEditText
.Usage:
Vous pouvez ressentir un peu de retard lors de la saisie rapide de texte si vous utilisez editText.setText () au lieu de editable.replace () .
la source
Astuce facile à corriger ... tant que votre logique pour dériver la nouvelle valeur de texte d'édition est idempotente (ce qu'elle serait probablement, mais simplement en disant). Dans votre méthode d'écoute, ne modifiez le texte d'édition que si la valeur actuelle est différente de la dernière fois que vous avez modifié la valeur.
par exemple,
la source
setText()
et le rajouter après.J'utilise de cette façon:
Et chaque fois que vous devez modifier le texte par programme, commencez par effacer
la source
Vous pouvez utiliser la syntaxe DSL Kotlin pour avoir la solution générique pour cela:
Et dans votre TextWatcher, vous pouvez l'utiliser comme:
la source
Cela fonctionne bien pour moi
la source
Le problème peut être facilement résolu en utilisant
tag
file et vous n'avez même pas à gérer le focus de editText.Définition du texte et de la balise par programmation
Vérification du
tag
in onTextChangedla source
Si vous avez besoin de rester concentré sur le
EditText
texte de changement, vous pouvez demander le focus:la source
essayez cette logique: je voulais setText ("") sans aller en boucle infinie et ce code fonctionne pour moi. J'espère que vous pouvez modifier cela pour répondre à vos besoins
la source
Voici une classe pratique qui fournit une interface plus simple que TextWatcher pour le cas normal de vouloir voir les changements au fur et à mesure qu'ils se produisent. Cela permet également d'ignorer le changement suivant comme l'OP l'a demandé.
Utilisez-le comme ceci:
Chaque fois que vous souhaitez modifier le contenu de
editText
sans provoquer une cascade de modifications récursives, procédez comme suit:la source
Ma variante:
Définir les écouteurs uniquement en utilisant setOnTextChangeListener () et définir le texte uniquement en utilisant setNewText (je voulais remplacer setText (), mais c'est définitif)
la source
J'ai créé une classe abstraite qui atténue le problème cyclique du moment où une modification du EditText est effectuée via un TextWatcher.
la source
Très simple, définissez le texte avec cette méthode
la source
Vous devez vous assurer que votre implémentation des modifications de texte est stable et ne change pas le texte si aucune modification n'est nécessaire. Normalement, ce serait tout contenu qui a déjà été via l'observateur une fois.
L'erreur la plus courante consiste à définir un nouveau texte dans le EditText associé ou dans Editable même si le texte n'a pas été réellement modifié.
En plus de cela, si vous apportez vos modifications à la vue modifiable au lieu d'une vue spécifique, vous pouvez facilement réutiliser votre observateur, et vous pouvez également le tester isolément avec des tests unitaires pour vous assurer qu'il a le résultat souhaité.
Comme Editable est une interface, vous pouvez même utiliser une implémentation factice qui lève une RuntimeException si l'une de ses méthodes est appelée pour essayer de changer son contenu, lors du test de contenu qui devrait être stable.
la source
Ma façon de faire la chose:
Dans le segment d'écriture
L'auditeur
Fonctionne quand même.
la source