Die TextWatcher
Schnittstelle verfügt über 3 Rückrufmethoden, die alle in der folgenden Reihenfolge aufgerufen werden, wenn eine Änderung am Text vorgenommen wurde:
beforeTextChanged(CharSequence s, int start, int count, int after)
Wird aufgerufen, bevor die Änderungen auf den Text angewendet wurden.
Der s
Parameter ist der Text, bevor eine Änderung angewendet wird.
Der start
Parameter ist die Position des Anfangs des geänderten Teils im Text.
Der count
Parameter ist die Länge des geänderten Teils in der s
Sequenz seit der start
Position.
Und der after
Parameter ist die Länge der neuen Sequenz, die den Teil der s
Sequenz von start
bis ersetzt start+count
.
Sie dürfen den Text in TextView
dieser Methode nicht ändern (mithilfe von myTextView.setText(String newText)
).
onTextChanged(CharSequence s, int start, int before, int count)
Ähnlich der beforeTextChanged
Methode, jedoch aufgerufen, nachdem sich der Text geändert hat.
Der s
Parameter ist der Text, nachdem Änderungen übernommen wurden.
Der start
Parameter ist der gleiche wie in der beforeTextChanged
Methode.
Der count
Parameter ist der after
Parameter in der beforeTextChanged-Methode.
Und der before
Parameter ist der count
Parameter in der beforeTextChanged-Methode.
Sie dürfen den Text in TextView
dieser Methode nicht ändern (mithilfe von myTextView.setText(String newText)
).
afterTextChanged(Editable s)
Sie können den Text in TextView
dieser Methode ändern .
/! \ Warnung: Wenn Sie den Text in ändern TextView
, TextWatcher
wird der erneut ausgelöst und eine Endlosschleife gestartet. Sie sollten dann wie eine boolean _ignore
Eigenschaft hinzufügen, die die Endlosschleife verhindert.
Beispiel:
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...
}
Zusammenfassung:
Eine gebrauchsfertige Klasse: TextViewListener
Persönlich habe ich meinen benutzerdefinierten Text-Listener erstellt, der mir die 4 Teile in separaten Zeichenfolgen gibt, was für mich viel intuitiver zu bedienen ist.
/**
* 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;
}
}
Beispiel:
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();
}
}