1. 程式人生 > >android如何為listview的每項中edittext控制元件新增textwacher

android如何為listview的每項中edittext控制元件新增textwacher

listview中的每項都有一個edittext,而且現在需要實時監聽該edittext的輸入,在listview的外部進行改變(例如使用者修改單價,外部的總價需要變化)

新增監聽器的程式碼:

public View getView(final int position, View arg1, ViewGroup arg2) {
		if (arg1 == null) {
			arg1 = inflater.inflate(R.layout.main_layout, null);
			final ViewHolder holder = new ViewHolder();
			holder.position = position;
			holder.et_price.addTextChangedListener(new TextWatcher() {
				@Override
				public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
				}

				@Override
				public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
				}

				@Override
				public void afterTextChanged(Editable arg0) {

					//do something use holder.position
				}
			});
			arg1.setTag(holder);
		}
		final ViewHolder holder = (ViewHolder) arg1.getTag();
		holder.position = position;
		return arg1;
	}
這樣就能夠保證,每個edittext的textwacher不會被新增多次,而且listview滑動的時候也能夠正確的工作

還有需要注意的是在textwacher裡面需要使用holder.position來表示當前edittext的位置,並且需要更新該holder的positioin


這時就要提到一個問題是,listview和gridview的getview 可能會呼叫多次,原因是如果listview的高度是wrap_content的話,listview就會去呼叫計運算元view的高度,最後來計算listview的整體高度,所以造成會呼叫多次:

詳細介紹

其實按照正常的角度來說,呼叫多次getview方法並沒有什麼錯誤,因為前面的getview方法返回的view並不會新增進入listview中,僅僅是用作計算高度,但是現在非常奇怪的現象是新增進listview中那個view裡面的edittext的textwacher會回撥很多次,而且回撥內容很奇怪,不明原因,所以解決辦法是修改textwacher裡面的回撥方法中加入

if (!holder.et_price.getRootView().getClass().toString().contains("DecorView")
	|| holder.et_price.getParent().getParent().getParent().getParent().getParent() == null)
	return;
if (holder.et_price.getParent().getParent() == null) 
	return;
兩個函式中的其中一個來標識該edittext的父view是否是被新增進listview中的那個view,暫時想到這個解決方法,具體原因也是不明白,有遇到的告訴小弟

還有一個是,listview巢狀listview,重寫內層listview的onmeasure方法,結果是裡面的listview會一次性呼叫所有項的getview方法,不會動態隨著螢幕的移動而複用convertview,所以這時內層listview的edittext不會出現edittext輸入了內容,拉倒螢幕外,再拉回這項之後,該edittext上次輸入的內容沒有儲存的情況。但是如果單獨一個listview+edittext就會出現這種情況,最好的辦法就是定義一個map去儲存每個edittext的輸入值