今天在改别人的项目时遇到一个问题,就是在修改EditText里面的内容时onTextChanged会执行多次,经过多次断点调试发现,他是通过一个接口回调的方式在适配器Adapter的getView方法中进行添加的addTextChangedListener
首先我们先看一下addTextChangedListener
addTextChangedListener.png可以看到这个
TextWatcher
是被存储到一个ArrayList中onTextChanged.png
在触发text改变事件时也是走的循环回调。
回到我们的adapter中发现getView方法只有第一次执行时convertView为空,也就是后面的item用的都是同一个View,这样在给EditText添加监听事件时相当于是重复添加。
为什么只有第一次执行时convertView为空
因为:ListView的android:layout_height属性值为"match_parent",如果为“wrap_content"将会是另一种情况。其适配器的getView方法里只有第一个Item的convertview为null其他的不为空。具体原因还没有搞清楚
解决办法
其实就算不是只有第一个Item的convertview为null,只要出现复用还是会出现这样的问题。所以:
//1、移除原来的文字改变监听,避免view复用所造成TextWatcher被多次调用
if(myTextWatcher !=null){
editAmount.removeTextChangedListener(myTextWatcher );
}
//2 创建TextWatcher
myTextWatcher =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){
}
};
//3 然后添加新的TextWatcher
editAmount.addTextChangedListener(myTextWatcher );
就是先removeTextChangedListener移除原有的监听,这样就只会保留我们当前设置的了。
参考文章
1.https://blog.csdn.net/duncan891101/article/details/19482109
2.https://blog.csdn.net/Jiang_Rong_Tao/article/details/90482602
网友评论