1.TextWatcher
使用TextWatcher可以实现对EditText输入的监听,调用EditText的addTextChangedListener(TextWatcher watcher)方法即可。
TextWatcher是一个接口类,所以必须实现TextWatcher里的3个方法:
public interface TextWatcher extends NoCopySpan {
public void beforeTextChanged(CharSequence s, int start, int count, int after);
public void onTextChanged(CharSequence s, int start, int before, int count);
public void afterTextChanged(Editable s);
}
2.监听器里的setText函数导致StackOverflowError错误
private TextWatcher mTextWatcher = 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) {
if (null == s || s.length() == 0) {
return;
}
String inputString = s.toString();
String finalString = getFormatedInputString(inputString);
if (!TextUtils.isEmpty(finalString)) {
mEditText.setText(finalString);
mEditText.setSelection(finalString.length());
}
}
@Override
public void afterTextChanged(Editable s) {
}
};
假如按照上面所写的,一定会产生bug:Java.lang.StackOverflowError
原因分析:在onTextChanged方法中,使用setText()方法,会重新触发监听器,并不断的进行递归,最后导致程序崩溃。
3.解决方法
(1)不要在监听器里写触发监听器的方法,特别是没有出口的方法相互调用。
(2)可以写一个标志位:flag,假如EditText内容发生变化,才执行setText()方法,如果没有发生变化,就不执行监听器里的setText()方法
private TextWatcher mTextWatcher = 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) {
if (null == s || s.length() == 0) {
return;
}
//setText()会回调onTextChanged(),增加标志位防止出现堆栈溢出
if (isChange) {
isChange = false;
return;
}
isChange = true;
String inputString = s.toString();
String finalString = getFormatedInputString(inputString);
if (!TextUtils.isEmpty(finalString)) {
mEditText.setText(finalString);
mEditText.setSelection(finalString.length());
}
}
@Override
public void afterTextChanged(Editable s) {
}
};