具有EditText值的Android ListView与TextWatcher复制 [英] Android ListView with EditText values duplicating with TextWatcher

查看:106
本文介绍了具有EditText值的Android ListView与TextWatcher复制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ViewHolder:

I have a ViewHolder:

import android.widget.EditText;
import android.widget.TextView;

public class ListViewHolder {
    TextView productName;
    EditText productStock;
}

还有我的ListAdapter(listProducts是一个Product对象的ArrayList):

And my ListAdapter (listProducts is an ArrayList of Product objects):

public Product getItem(int position){
    return listProducts.get(position);
}


public View getView(final int position, View convertView, ViewGroup parent){
    View row;
    final ListViewHolder listViewHolder;

    if(convertView == null){
        LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        row = layoutInflater.inflate(R.layout.set_stock_listview,parent,false);
        listViewHolder = new ListViewHolder();
        listViewHolder.productName = (TextView) row.findViewById(R.id.productName);
        listViewHolder.productStock = (EditText) row.findViewById(R.id.productStock);
        row.setTag(listViewHolder);
    }
    else{
        row = convertView;
        listViewHolder = (ListViewHolder) row.getTag();
    }

    final Product product = getItem(position);

    if(product.getDesiredQuantity()>0){
        listViewHolder.productStock.setText(String.valueOf(product.getDesiredQuantity()));
    }

    listViewHolder.productName.setText(product.getName()+":");
    listViewHolder.productStock.setInputType(InputType.TYPE_CLASS_NUMBER);
    listViewHolder.productStock.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
        }

        @Override
        public void afterTextChanged(Editable editable) {
            product.setDesiredQuantity(Integer.valueOf(editable.toString()));
        }
    });
    return row;
}

但是,在列表中滚动时,EditText的值会复制到许多其他行.看来还必须更新其他Product对象,但是我找不到问题,有什么主意吗?

However when scrolling through the list, the value of the EditText duplicates to many of the other rows. It looks like it must be updating the other Product objects also but I haven't been able to find the issue, any ideas?

推荐答案

这个问题是由于视图可以被回收(通过convertView参数)和TextView仅允许您 add 一个TextWatcher.在您发布的代码中,每次用非空的convertView调用getView()时,您将创建一个 additional TextWatcher并将其分配给productStock ...以前的观察者将留在原处,以更新先前绑定的product.

The problem is a combination of the fact that views can be recycled (via the convertView argument) and the fact that TextView only allows you to add a TextWatcher. In the code you've posted, every time getView() is called with a non-null convertView, you will create an additional TextWatcher and assign it to productStock... and the previous watchers will remain in place updating the previously-bound product.

如果现有的TextWatcher有一个,则必须将其删除.我建议使用ListViewHolder完成此操作.

You have to remove the existing TextWatcher if it has one. I recommend using the ListViewHolder to accomplish this.

public class ListViewHolder {
    TextView productName;
    EditText productStock;
    TextWatcher productStockWatcher;
}

然后更改此内容:

listViewHolder.productStock.addTextChangedListener(new TextWatcher() { ... });

对此:

if (listViewHolder.productStockWatcher != null) {
    listViewHolder.productStock.removeTextChangedListener(productStockWatcher);
}

listViewHolder.productStockWatcher = new TextWatcher() { ... };
listViewHolder.productStock.addTextChangedListener(listViewHolder.productStockWatcher);

这篇关于具有EditText值的Android ListView与TextWatcher复制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆