带有edittext和textwatcher的Listview. Textwatcher触发多次(超过3次) [英] Listview with edittext and textwatcher. Textwatcher fires multiple times (more than 3 times)

查看:102
本文介绍了带有edittext和textwatcher的Listview. Textwatcher触发多次(超过3次)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义列表适配器,其中一个列表项包含三个编辑文本.我有一个约会选择器.设置日期后,适配器的相应模型将正确保存日期.但是对于其他编辑文本,我只希望将输入的文本存储在列表中.我使用textwatcher来完成任务.我的问题是,文本查看器会为视图中的单个条目触发多次(准确地说是5次).

I have a custom list adapter with one list item having three edit texts. And I Have a date picker for one of them. When a date is set, the corressponding model for the adapter is saved with the date correctly. But for the other edit texts, i just want the entered text to be stored in the list. And I use textwatcher to accomplish the task. My problem is the text watcher fires multiple times (5 times to be exact) for a single entry in the view.

如果其中一个编辑文本可以正常工作,为什么另一个文本不能呢?我真的可以使用一些帮助.到目前为止,我一直找不到任何成功.

If one of the edit texts works correctly, why not the other? I could really use some help. I've been unable to find any success so far.

public class AddExpensesAdapter extends BaseAdapter{
private Activity activity;
private ArrayList<AddExpensesModel> addExpensesList;
private LayoutInflater inflater;
private  TextView totalAmount;
private ArrayList<String> array_amount= new ArrayList<String>();
private ArrayList<String> array_name= new ArrayList<String>();
public AddExpensesAdapter(Activity activity, ArrayList<AddExpensesModel> addExpensesList)        {
    this.activity = activity;
    this.addExpensesList = addExpensesList;
    this.inflater = (LayoutInflater) this.activity
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

@Override
public int getCount() {
    return addExpensesList.size();
}

@Override
public Object getItem(int position) {
    return null;
}

@Override
public long getItemId(int position) {
    return 0;
}

public AddExpensesModel getExpenseModel(int position)
{
    return addExpensesList.get(position);
}

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    final ViewHolder viewHolder;
    if (convertView == null) {
        viewHolder = new ViewHolder();
        convertView = inflater.inflate(R.layout.a_add_expenses_listitem, null);


        viewHolder.expenseName = (EditText) convertView.findViewById(R.id.add_expenses_et_expense_name);
        viewHolder.dateTime = (EditText) convertView.findViewById(R.id.add_expenses_et_date_time);
        viewHolder.amount = (EditText) convertView.findViewById(R.id.add_expenses_et_amount);
        viewHolder.editDate = (ImageView) convertView.findViewById(R.id.add_expenses_edit_date);
        viewHolder.number = (TextView) convertView.findViewById(R.id.add_expenses_tv_serial_number);
        viewHolder.deleteExpense = (ImageView) convertView.findViewById(R.id.add_expenses_delete_expense);
        // viewHolder.totalfriends = (TextView)
        // convertView.findViewById(R.id.eventtotalfriends);

        convertView.setTag(viewHolder);
        viewHolder.ref = position;
    } else {
        viewHolder = (ViewHolder) convertView.getTag();

    }


    final AddExpensesModel addExpenseModel = addExpensesList.get(position);

    viewHolder.expenseName.setText(addExpenseModel.getExpenseName());
    viewHolder.dateTime.setText(addExpenseModel.getDateTime());
    viewHolder.amount.setText(addExpenseModel.getAmount());
    viewHolder.number.setText(""+(position+1)+".");




    viewHolder.editDate.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            try {
                setDate(addExpenseModel);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });

    viewHolder.deleteExpense.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            addExpensesList.remove(position);
            notifyDataSetChanged();
        }
    });


        viewHolder.amount.addTextChangedListener(new TextWatcher() {

            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {

            }

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

            }

            @Override
            public void afterTextChanged(Editable editable) {

                if(!editable.toString().equals(""))
                {


                                addExpenseModel.setAmount(editable.toString());

                        }


                    notifyDataSetChanged();

            }
        });

    return convertView;
}



public void setDate(final AddExpensesModel model) throws Exception {

    final String dateFormatPattern = "MMM, dd yyyy";
    final SimpleDateFormat sdf = new SimpleDateFormat(dateFormatPattern,
            Locale.getDefault());

    DatePickerDialog.OnDateSetListener date = new DatePickerDialog.OnDateSetListener() {
        @Override
        public void onDateSet(DatePicker view, int year, int monthOfYear,
                              int dayOfMonth) {
            Calendar cal = Calendar.getInstance();
            cal.set(Calendar.YEAR, year);
            cal.set(Calendar.MONTH, monthOfYear);
            cal.set(Calendar.DAY_OF_MONTH, dayOfMonth);
            model.setDateTime(sdf.format(cal.getTime()));
            notifyDataSetChanged();
        }
    };

    Calendar cal = Calendar.getInstance();
    cal.setTime(sdf.parse(model.getDateTime()));
    new DatePickerDialog(this.activity, date, cal.get(Calendar.YEAR),
            cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH)).show();
}

static class ViewHolder {
    EditText expenseName;
    EditText dateTime;
    EditText amount;
    ImageView editDate;
    ImageView deleteExpense;
    TextView number;

}

}

推荐答案

我知道我来晚了,但是我会把这里留给以后的读者.由于文本观察者具有可回收性,并且将文本观察者添加到编辑文本中而不被替换,因此将文本观察者设置为列表视图项有些棘手.因此,每次创建行视图或将其绑定到新数据时,都需要删除不正确的监视程序并添加新的观察程序.尝试以下实现:

I know I'm late, but I'll leave this here for future readers. It's a bit tricky to set textwatchers to listview items due to their recycling nature and also since Textwatchers are added to an edit text and not replaced. So you need to remove the incorrect ones and add new watchers everytime a row view is created or bound to new data. Try the following implementation:

1)自定义文本观察器. (对象项是包含行数据的对象)

1) The custom text watcher. (Object item is the object that contains your row data)

private class CustomWatcher implements TextWatcher
{
    private Object item;

    private CustomWatcher(Object item)
    {
        this.item = item;
    }

    @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)
    {

    }
}

2)将textwatcher添加到您的edittext中,并在getView()函数中删除前一个.

2) Add the textwatcher to your edittext and remove the previous one, inside your getView() function.

CustomWatcher oldWatcher = (CustomWatcher)holder.editDate.getTag();
    if(oldWatcher != null)
        holder.editDate.removeTextChangedListener(oldWatcher);

//populate your editText with the model data here (before adding the new text watcher)

CustomWatcher newWatcher = new CustomWatcher(rowItem);
    holder.editDate.setTag(newWatcher);
    holder.editDate.addTextChangedListener(newWatcher);

完成.现在,您可以将文本保存在相应的行数据对象中.这样,当您的Textwatchers的使用期限超过其用途时,它们就会被删除,并且还可以防止内存泄漏.

Done. You can now save the text in the corresponding row data object. This way, your Textwatchers will get removed when they have outlived their usefulness and prevent memory leaks as well.

这篇关于带有edittext和textwatcher的Listview. Textwatcher触发多次(超过3次)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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