Je veux attraper un événement lorsque l'utilisateur finit de modifier l'EditText.
Comment faire ?
Je veux attraper un événement lorsque l'utilisateur finit de modifier l'EditText.
Comment faire ?
Mieux encore, vous pouvez également utiliser l'écouteur EditText onFocusChange pour vérifier si l'utilisateur a terminé l'édition : (Il n'est pas nécessaire que l'utilisateur appuie sur la touche Done ou Enter du clavier logiciel).
((EditText)findViewById(R.id.youredittext)).setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
// When focus is lost check that the text field has valid values.
if (!hasFocus) { {
// Validate youredittext
}
}
});
Note : Pour plus d'un EditText, vous pouvez aussi laisser votre classe implémenter View.OnFocusChangeListener
puis définissez les listeners pour chacun de vos EditText et validez-les comme ci-dessous
((EditText)findViewById(R.id.edittext1)).setOnFocusChangeListener(this);
((EditText)findViewById(R.id.edittext2)).setOnFocusChangeListener(this);
@Override
public void onFocusChange(View v, boolean hasFocus) {
// When focus is lost check that the text field has valid values.
if (!hasFocus) {
switch (view.getId()) {
case R.id.edittext1:
// Validate EditText1
break;
case R.id.edittext2:
// Validate EditText2
break;
}
}
}
Cela ne fonctionne pas s'il n'y a qu'une seule cible. EditText
. Il ne perdra jamais le fil.
Quelle est la meilleure façon de procéder si nous n'avons qu'un seul EditText
? Dois-je utiliser onEditorAction
?
S'il n'y a qu'un seul EditText
vous validez sur ce que l'utilisateur fait pour quitter l'écran.
Lorsque l'utilisateur a fini de modifier le texte, il appuie sur la touche Done
o Enter
((EditText)findViewById(R.id.youredittext)).setOnEditorActionListener(
new EditText.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH ||
actionId == EditorInfo.IME_ACTION_DONE ||
event != null &&
event.getAction() == KeyEvent.ACTION_DOWN &&
event.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
if (event == null || !event.isShiftPressed()) {
// the user is done typing.
return true; // consume.
}
}
return false; // pass on to other listeners.
}
}
);
Pouvez-vous en être sûr ? J'ai l'habitude d'appuyer sur le champ éditable suivant - je n'appuie pratiquement jamais sur Enter/Done - et d'après ce que j'ai vu de nos clients, eux non plus... Je parle d'une liste d'Edittexts/Comboboxes etc. Si vous ne donnez à l'utilisateur qu'un seul champ de saisie et que vous l'obligez à appuyer sur un bouton avant de pouvoir passer aux autres champs, c'est évidemment une autre histoire...
N'oubliez pas que vous devez également définir Android:singleLine="true" pour votre texte d'édition. Merci à stackoverflow.com/questions/15901863/
Bonne solution mais peut se planter avec un pointeur nul... event' peut être nul sur l'action Done, donc event.isShiftPressed() se plante. Si vous utilisez cette solution, ajoutez des contrôles de pointeur nul.
Vous pouvez le faire en utilisant setOnKeyListener ou en utilisant un textWatcher comme :
Définir l'observateur de texte editText.addTextChangedListener(textWatcher);
puis appeler
private TextWatcher textWatcher = new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
//after text changed
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
};
Je crains que ce ne soit pas la solution (complète) - le textWatcher se déclenche après chaque édition - si vous tapez hello, il va se déclencher pour h, e, l, l et o - il ne sait pas vraiment quand l'utilisateur a "fini". Ce serait génial si le TextWatcher pouvait savoir quand le widget perd le focus et que l'utilisateur passe à autre chose...
Les deux réponses @Reno et @Vinayak B ensemble si vous voulez cacher le clavier après l'action
textView.setOnEditorActionListener(new EditText.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_ACTION_DONE) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(textView.getWindowToken(), 0);
return true;
}
return false;
}
});
textView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
// your action here
}
}
});
Bien que de nombreuses réponses aillent dans la bonne direction, je pense qu'aucune d'entre elles ne répond à ce à quoi l'auteur de la question pensait. Ou du moins, j'ai compris la question différemment car je cherchais une réponse à un problème similaire. Le problème est "Comment savoir quand l'utilisateur arrête de taper sans qu'il appuie sur un bouton" et déclencher une action (par exemple l'auto-complétion). Si vous voulez faire cela, démarrez le timer dans onTextChanged avec un délai que vous considérez que l'utilisateur a arrêté de taper (par exemple 500-700ms), pour chaque nouvelle lettre quand vous démarrez le timer, annulez le précédent (ou au moins utilisez une sorte de drapeau que quand ils cochent, ils ne font rien). Voici un code similaire à celui que j'ai utilisé :
new Timer().schedule(new TimerTask() {
@Override
public void run() {
if (!running) {
new DoPost().execute(s.toString());
});
}
}, 700);
Notez que je modifie le drapeau booléen en cours d'exécution dans ma tâche asynchrone (la tâche reçoit le json du serveur pour l'autocomplétion).
Gardez également à l'esprit que cela crée de nombreuses tâches de minuterie (je pense qu'elles sont programmées sur le même Thread thou mais il faudrait le vérifier), il y a donc probablement de nombreux endroits à améliorer mais cette approche fonctionne également et l'essentiel est que vous devriez utiliser une minuterie puisqu'il n'y a pas d'événement "User stopped typing".
L'essentiel du code est dans la réponse, pour un exemple plus détaillé, voir la réponse de ZimaXXX sur cette même page qui utilise la même approche. Je ne sais pas quelles autres informations je pourrais ajouter, si vous pouvez préciser ce qui n'est pas clair, j'essaierai d'ajouter des détails.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
1 votes
@PadmaKumar La façon la plus naturelle serait de perdre le focus sur l'EditText - alors l'utilisateur a définitivement terminé. Cependant, d'après mon expérience, il semble que tous les widgets Android ne récupèrent pas correctement le focus (j'ai eu ces problèmes avec les Spinners et les Buttons) - donc d'autres widgets pourraient ne pas perdre le focus...
3 votes
Pourquoi une si grande plateforme nous laisse-t-elle nous occuper de ce genre de fonctions simples ? google ne perdra rien à ajouter de telles fonctions principales à ses bibliothèques de support au moins.
0 votes
Si vous connaissez la longueur exacte de la chaîne que l'utilisateur va saisir, récupérez le texte dans afterTextChanged. Ex :
override fun afterTextChanged(s: Editable?) { if (s.toString().length == 5) { val enteredString = s.toString() }
2 votes
Je me gratte la tête en me demandant pourquoi cela est si difficile dans Android que nous (moi y compris) devons chercher et lancer une discussion en ligne et de nombreuses solutions différentes avec 10+ lignes de code ?