ListView中嵌入一个或多个EditText导致数据混乱解决方法

时间:2021-12-02 09:30:02
[vio.wang 崇尚开源 尊重原创] 转载请声明出处. http://blog.csdn.net/violetic/article/details/42392723

    关于ListView嵌入一个或多个EditText导致数据混乱,一直是个一个老生常谈的问题.在开发过程中常遇见,在各个网站上都没有一个很好的解决方法.动态添加view不失为一种方法[此处不详谈,自行百度].但是数据量大的话,就显得过于繁琐,且效率低,无法回收,对内存资源也过于浪费.以下方法说起来也简单,一看就明白.

    在这里,我发一下自己的见解,或许浅薄,诸君见谅.抛砖引玉,博各位大神一言.

    关于ListView嵌入多个EditText导致数据混乱的原因探讨:

    在EditView源码中,我们不难发现EditText是继承于TextView,默认赋予了EditText焦点.而在ListView的源码中,我们会发现google对ListView进行了一番优化,当ListView的item滚出屏幕时,item会被回收掉.那么问题来了,学挖...咳,我们在重新利用item的时候,由于我们在ListView上嵌了EditText,EditText的焦点并不会随着item被回收系统回收掉.(Google挖坑啊),那么这个item上的EditView就会被赋予焦点,那么我们的数据该放在哪儿呢?一滑数据就会乱掉.


    解决方法:自定义EditView继承自EditText

public class CLEditText extends EditText {
private ArrayList<TextWatcher> mListeners = null;

public CLEditText(Context ctx) {
super(ctx);
}

public CLEditText(Context ctx, AttributeSet attrs) {
super(ctx, attrs);
}

public CLEditText(Context ctx, AttributeSet attrs, int defStyle) {
super(ctx, attrs, defStyle);
}

@Override
public void addTextChangedListener(TextWatcher watcher) {
if (mListeners == null) {
mListeners = new ArrayList<TextWatcher>();
}
mListeners.add(watcher);

super.addTextChangedListener(watcher);
}

@Override
public void removeTextChangedListener(TextWatcher watcher) {
if (mListeners != null) {
int i = mListeners.indexOf(watcher);
if (i >= 0) {
mListeners.remove(i);
}
}

super.removeTextChangedListener(watcher);
}

public void clearTextChangedListeners() {
if (mListeners != null) {
for (TextWatcher watcher : mListeners) {
super.removeTextChangedListener(watcher);
}

mListeners.clear();
mListeners = null;
}
}
}
      看到这段代码,应该就明白个大概了.(如果没看明白也不用急),addTextChangedListener,removeTextChangedListener这两个方法是哪来的呢???一路ctrl左键,你就会发现这是出自TextView,没错,EditText就是继承自TextView.下面重点:clearTextChangedListeners这个方法才是重点.我们在这里做的就是清除所有获取到的TextWatcher.

      接下来,我们只需要与一般的自定义View一样在xml中用CLEditText替代EditText.

      最后.在代码中,我们在ListView的Adapter的getView中,按如下操作即可.

        ViewHodler hodler = null;
if (convertView == null) {
convertView = layoutInflater.inflate(
R.layout.in_list_ch, null);
hodler = new ViewHodler();
hodler.s = (TextView) convertView
.findViewById(R.id.tv_sk);
convertView.setTag(hodler);
} else {
hodler = (ViewHodler) convertView.getTag();
holder.s.clearTextChangedListeners();
}
      ok,多个EditText同样操作,如有更好建议,请留言.