我有一个自定义列表适配器,其中一个列表项具有三个编辑文本。我为其中一个提供了日期选择器。设置日期后,适配器的相应模型会与日期正确保存。但是对于其他编辑文本,我只想将输入的文本存储在列表中。我使用 textwatcher 来完成任务。我的问题是文本观察器为 View 中的单个条目多次触发(准确地说是 5 次)。

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

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;

}

}

最佳答案

我知道我迟到了,但我会把它留在这里给 future 的读者。将 textwatchers 设置为 listview 项目有点棘手,因为它们的回收性质以及 Textwatchers 被添加到编辑文本中而不是被替换。因此,每次创建行 View 或绑定(bind)到新数据时,您都需要删除不正确的观察者并添加新的观察者。尝试以下实现:

  • 自定义文本观察器。 (对象项是包含您的行数据的对象)
    私有(private)类 CustomWatcher 实现 TextWatcher
    {
    私有(private)对象项;
     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)
     {
    
     }
    
    }
  • textwatcher 添加到您的 edittext 并删除前一个,在您的 getView() 函数中。
    CustomWatcher oldWatcher = (CustomWatcher)holder.editDate.getTag();
    if(oldWatcher != null)
    holder.editDate.removeTextChangedListener(oldWatcher);
    //在这里用模型数据填充你的editText(在添加新的文本观察器之前)
    CustomWatcher newWatcher = new CustomWatcher(rowItem);
    holder.editDate.setTag(newWatcher);
    holder.editDate.addTextChangedListener(newWatcher);

  • 完毕。您现在可以将文本保存在相应的行数据对象中。这样,您的 Textwatcher 将在其使用生命周期结束时被删除,并防止内存泄漏。

    10-08 03:14