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());
// 做处理...
}

你可能感兴趣的:(Android问题)