ListView中嵌入一個或多個EditText導致數據混亂解決方法

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





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章