關於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同樣操作,如有更好建議,請留言.