1. 程式人生 > >ListView資料錯位常見問題與解決方案

ListView資料錯位常見問題與解決方案

問題一:ListView中,複用機制導致EditView的輸入資料錯位?

解決方法:Adapter呼叫getViewEditView設定相應的值

1、預設清除所有EditView的焦點,即呼叫clearFocus()方法;

holder.et.clearFocus();

2、儲存每個ItemEditView所對應的輸入值,並在Adapter呼叫getView時進行setText()

holder.et.setText(mDatas.get(position).getContent());

問題二:ListView中,EditView新增文字監聽addTextChangeListener時,為EditView

設定對應資料後會觸發文字監聽導致資料有誤或無限觸發?

解決方法:這與ListView的複用機制無關,是文字改變監聽的使用不當導致的,只要在適當時候移除監聽即可。

方法一:定義一個boolean變數做文字操作標誌

1、Adapter中定義一個boolean型別成員變數;

private boolean mIsChange = false;

2、EditText設定對應資料即在setText()方法前將標誌設為true,在setText()方法後將標誌設為false

mIsChange = true;
holder.et.setText(mDatas.get(position).getContent());
mIsChange = false;

3、在文字監聽中判斷標誌不為true再做事情。

ew 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) {
        if (!mIsChange) {
            // 做處理...
        }
    }

方法二:適當移除監聽

1、預設清除所有EditView的焦點,即呼叫clearFocus()方法;

holder.et.clearFocus();

2、單獨new TextWatcher()物件;

final TextWatcher tw1 = 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、緊接在所有控制元件findViewById後為EditText新增焦點監聽setOnFocusChangeListener,判斷取得焦點時新增監聽addTextChangeListener,失去焦點時移除監聽removeTextChangedListener,這樣只有我們在點選輸入框即輸入時進行監聽輸入情況;

holder.et.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (hasFocus) {
            holder.et_curNum.addTextChangedListener(tw1);
        } else {

            holder.et_curNum.removeTextChangedListener(tw1);
        }
    }
});

注:也可以直接設定完監聽後,在為EditText設定對應資料前移除監聽,設定完後新增監聽。

還有就是無限觸發文字改變監聽的問題,主要是你在監聽文字改變方法中呼叫setText()前沒有先移除監聽,在設定完再重新新增監聽。

@Override
public void afterTextChanged(Editable s) {
holder.et_addNum.removeTextChangedListener(this);
older.et.setText(mDatas.get(position).getContent());
    holder.et_addNum.addTextChangedListener(this);
}

問題三:ListView中,EditView新增文字監聽addTextChangeListener時,更改資料notifyDataSetChaged()後,對EditText輸入資料後,資料發生錯位?

解決方法:當你在文字監聽方法中輸出getView傳進來的position時,你會發現與你資料的位置對不上號,這是複用機制導致的,只要儲存Item對應資料的position

1、getView中為控制元件設定值時用setTag()方法把position繫結給EditText

holder.et.setText(mDatas.get(position).getContent());
holder.et.setTag(position);

2、在文字監聽方法中不要使用geiView傳進來的position值,而是使用我們繫結的position值。

@Override
public void afterTextChanged(Editable s) {
    int position = Integer.valueOf(holder.et_addNum.getTag().toString());
// 做處理...
}