L' TextWatcher
interface dispose de 3 méthodes de rappel qui sont toutes appelées dans l'ordre suivant lorsqu'une modification est apportée au texte:
beforeTextChanged(CharSequence s, int start, int count, int after)
Appelé avant que les modifications aient été appliquées au texte.
Le s
paramètre est le texte avant toute modification.
Le start
paramètre est la position du début de la partie modifiée dans le texte.
Le count
paramètre est la longueur de la pièce modifiée dans la s
séquence depuis la start
position.
Et le after
paramètre est la longueur de la nouvelle séquence qui remplacera la partie de la s
séquence de start
à start+count
.
Vous ne devez pas modifier le texte TextView
de cette méthode (en utilisant myTextView.setText(String newText)
).
onTextChanged(CharSequence s, int start, int before, int count)
Similaire à la beforeTextChanged
méthode mais appelée après la modification du texte.
Le s
paramètre est le texte une fois les modifications appliquées.
Le start
paramètre est le même que dans la beforeTextChanged
méthode.
Le count
paramètre est le after
paramètre de la méthode beforeTextChanged.
Et le before
paramètre est le count
paramètre de la méthode beforeTextChanged.
Vous ne devez pas modifier le texte TextView
de cette méthode (en utilisant myTextView.setText(String newText)
).
afterTextChanged(Editable s)
Vous pouvez modifier le texte dans le à TextView
partir de cette méthode.
/! \ Attention: Lorsque vous modifiez le texte dans TextView
, le TextWatcher
sera de nouveau déclenché, commençant une boucle infinie. Vous devez alors ajouter comme une boolean _ignore
propriété qui empêche la boucle infinie.
Exemple:
new TextWatcher() {
boolean _ignore = false; // indicates if the change was made by the TextWatcher itself.
@Override
public void afterTextChanged(Editable s) {
if (_ignore)
return;
_ignore = true; // prevent infinite loop
// Change your text here.
// myTextView.setText(myNewText);
_ignore = false; // release, so the TextWatcher start to listen again.
}
// Other methods...
}
Résumé:
Une classe prête à l'emploi: TextViewListener
Personnellement, j'ai fait mon écouteur de texte personnalisé, ce qui me donne les 4 parties dans des chaînes séparées, ce qui est, pour moi, beaucoup plus intuitif à utiliser.
/**
* Text view listener which splits the update text event in four parts:
* <ul>
* <li>The text placed <b>before</b> the updated part.</li>
* <li>The <b>old</b> text in the updated part.</li>
* <li>The <b>new</b> text in the updated part.</li>
* <li>The text placed <b>after</b> the updated part.</li>
* </ul>
* Created by Jeremy B.
*/
public abstract class TextViewListener implements TextWatcher {
/**
* Unchanged sequence which is placed before the updated sequence.
*/
private String _before;
/**
* Updated sequence before the update.
*/
private String _old;
/**
* Updated sequence after the update.
*/
private String _new;
/**
* Unchanged sequence which is placed after the updated sequence.
*/
private String _after;
/**
* Indicates when changes are made from within the listener, should be omitted.
*/
private boolean _ignore = false;
@Override
public void beforeTextChanged(CharSequence sequence, int start, int count, int after) {
_before = sequence.subSequence(0,start).toString();
_old = sequence.subSequence(start, start+count).toString();
_after = sequence.subSequence(start+count, sequence.length()).toString();
}
@Override
public void onTextChanged(CharSequence sequence, int start, int before, int count) {
_new = sequence.subSequence(start, start+count).toString();
}
@Override
public void afterTextChanged(Editable sequence) {
if (_ignore)
return;
onTextChanged(_before, _old, _new, _after);
}
/**
* Triggered method when the text in the text view has changed.
* <br/>
* You can apply changes to the text view from this method
* with the condition to call {@link #startUpdates()} before any update,
* and to call {@link #endUpdates()} after them.
*
* @param before Unchanged part of the text placed before the updated part.
* @param old Old updated part of the text.
* @param aNew New updated part of the text?
* @param after Unchanged part of the text placed after the updated part.
*/
protected abstract void onTextChanged(String before, String old, String aNew, String after);
/**
* Call this method when you start to update the text view, so it stops listening to it and then prevent an infinite loop.
* @see #endUpdates()
*/
protected void startUpdates(){
_ignore = true;
}
/**
* Call this method when you finished to update the text view in order to restart to listen to it.
* @see #startUpdates()
*/
protected void endUpdates(){
_ignore = false;
}
}
Exemple:
myEditText.addTextChangedListener(new TextViewListener() {
@Override
protected void onTextChanged(String before, String old, String aNew, String after) {
// intuitive usation of parametters
String completeOldText = before + old + after;
String completeNewText = before + aNew + after;
// update TextView
startUpdates(); // to prevent infinite loop.
myEditText.setText(myNewText);
endUpdates();
}
}