异常类似如下:
java.lang.IndexOutOfBoundsException: Index: 2, Size: 1
at java.util.ArrayList.get(ArrayList.java:411)
at android.widget.TextView.sendAfterTextChanged(TextView.java:8211)
at android.widget.TextView$ChangeWatcher.afterTextChanged(TextView.java:10390)
at android.text.SpannableStringBuilder.sendAfterTextChanged(SpannableStringBuilder.java:1218)
这种情况很可能是由于EditText多次addTextChangedListener(…)之后,又调用removeTextChangeListener(…)造成的。
说说我的应用场景:
有一个输入框E,需要监听这个输入框E,当发现输入框E的内容改变之后,做了一下操作之后,就不再监听该输入框E了,防止做一些无用功,耗费资源,当点击按钮B搜索之后,又要重新监听这个输入框E,当内容发生改变,再及时作出响应,如此反复进行。
而造成异常的原因,正是因为添加了两次监听,重现步骤:
初始化EditText的时候,监听一次,此时没有输入任何内容,点击搜索按钮,又监听了一次,此时如果改变EditText内容,调用removeTextChangeListener(…),即发生闪退。
所以,在点击搜索之后,我们要判断该EditText是否已经有监听了,没有监听才进行添加。我们使用一个成员变量来记住EditText是否被监听,类似如下代码:
// 输入框是否还有监听者
private boolean hasListener;
初始化:
mSearchWatcher = 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) {
}
@Override
public void afterTextChanged(Editable s) {
removeTextChangeListener();
resetSearch();
}
};
addTextChangeListener();
/**
* 监听搜索框
*/
private void addTextChangeListener() {
if (et_search != null && mSearchWatcher != null && !hasListener) {
et_search.addTextChangedListener(mSearchWatcher);
hasListener = true;
}
}
/**
* 不再监听搜索框
*/
private void removeTextChangeListener() {
if (et_search != null && mSearchWatcher != null && hasListener) {
et_search.removeTextChangedListener(mSearchWatcher);
hasListener = false;
}
}
onClick()方法里,点击“搜索”按钮之后,恢复监听:
// 点击搜索,恢复监听
addTextChangeListener();