安卓 - 在自定义ArrayAdapter中绑定ListView中的EditText - 跟踪更改

8
我有一个Android活动,其中我有一个ListView绑定到自定义ArrayAdapter。每个ListView的行都有两个EditText(数字)字段。
ArrayAdapter最初是从SQLite DB填充的。但是,用户可以在ListView末尾添加一行,或者(通过长按某一行)删除ListView中的任何行。当他们点击“保存”按钮时,他们的更改将被保存。
我通过在ArrayAdapter的getView()方法中附加CustomTextWatcher以进行更改跟踪,为每个EditText的AfterTextChanged()事件传递EditText和ArrayAdapter项目列表中相应的对象,然后设置该对象的匹配属性 为EditText的内容。这样,在保存时,我可以简单地迭代基础对象列表并进行适当的数据库更改,知道对象列表是最新的。
适配器类和CustomTextWatcher的代码:
private class CustomAdapter extends ArrayAdapter<DataItem> {
    private ArrayList<DataItem> items;

    public CustomAdapter(Context context, int textViewResourceId, ArrayList<DataItem> items) {
        super(context, textViewResourceId, items);
        this.items = items;
}

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
            View v = convertView;

            DataItem wed = items.get(position);

            if (v == null) {
                LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                v = vi.inflate(R.layout.log_exercise_row, null);
            }

            if(wed != null)
            {
                     EditText text1 = (EditText) v.findViewById(R.id.text1);
                     EditText text2 = (EditText) v.findViewById(R.id.text2);

                text1.addTextChangedListener(new CustomTextWatcher(text1,wed));
                text2.addTextChangedListener(new CustomTextWatcher(text2,wed));


                int weight = wed.getWeight();

                if(weight != -1)
                {
                   text1.setText(weight+"");
                }


                int reps = wed.getReps();

                if(reps != -1)
                {
                    text2.setText(reps+"");
                }


            }

            return v;
    }

private class CustomTextWatcher implements TextWatcher {

    private EditText EditText; 
    private DataItem item;

    public CustomTextWatcher(EditText e, DataItem item)
    {
        this.EditText = e;
        this.item = item;
    }

    @Override
    public void afterTextChanged(Editable arg0) {

        String text = arg0.toString();

        if(text != null && text.length() > 0)
        {
            int val;

            try
            {
                val =Integer.parseInt(text);
            }

            catch(NumberFormatException e)
            {
                val=-1;
            }

            if(EditText.getId()==R.id.weightEditText)
            {
                item.setWeight(val);
            }

            else if(EditText.getId()==R.id.repsEditText)
            {
                item.setRepetitions(val);
            }
        }
    }

这一切都很好,除非当添加或删除项目时,EditText内容会产生不必要的重复。

举个例子:

从3行开始,所有EditText都为空
在第2行中,输入“5”,“6”
单击“More”->在结尾添加一个(空)行。现在有4行。
删除最后一行->显示3行,但第2行和第3行现在显示“5”,“6”->???????

看起来,在重新绑定之后,ListView中EditText对象的相对位置不稳定,这就导致了问题。例如,EditText对象“X”从位置3开始,然后在重新绑定后位于位置1 - 但它仍然具有附加到位置3中的数据对象的CustomTextWatcher。另一个问题是addTextChangedListener()不会影响已经附加到EditText的TextWatchers。

我对Android还很陌生,所以我不确定是否有更好的方法来解决我的问题。感谢任何帮助。

1个回答

10

看起来我需要一个自定义的('ViewHolder')类,以便在每次数据'绑定'时正确地同步EditText和其关联的数据对象之间的引用。此外,在getView()方法中仅在convertView对象为null时放置事件侦听器调用,意味着每个EditText对象只添加了一个侦听器。

感谢http://www.vogella.de/articles/AndroidListView/article.html#listsactivity指导我朝着正确的方向前进。

public class CustomAdapter extends ArrayAdapter<DataItem> {
private ArrayList<DataItem> items;
private Activity Context;

public CustomAdapter(Activity context, int textViewResourceId, ArrayList<DataItem> items) {
    super(context, textViewResourceId, items);
    this.items = items;
    this.Context = context; 
}

static class ViewHolder {
    protected EditText weight;
    protected EditText reps;

}

 public View getView(int position, View convertView, ViewGroup parent) {
        View v = convertView;

        DataItem wed = items.get(position);


        if (v == null) {
            LayoutInflater inflator = Context.getLayoutInflater();
            v = inflator.inflate(R.layout.log_exercise_row, null);
            final ViewHolder viewHolder = new ViewHolder();
            viewHolder.text1 = (EditText) v.findViewById(R.id.text1);
            viewHolder.text2 = (EditText) v.findViewById(R.id.text2);


            viewHolder.text1.addTextChangedListener(new CustomTextWatcher(viewHolder, viewHolder.text1));
            viewHolder.text2.addTextChangedListener(new CustomTextWatcher(viewHolder, viewHolder.text2));

            v.setTag(viewHolder);
            viewHolder.text1.setTag(wed);
            viewHolder.text2.setTag(wed);

        }

        else
        {
            ViewHolder holder = (ViewHolder) v.getTag();
            holder.text1.setTag(wed);
            holder.text2.setTag(wed);   
        }

        ViewHolder holder = (ViewHolder) v.getTag();

        // set values

        if(wed.getWeight() != -1)
        {
            holder.text1.setText(wed.getWeight()+"");
        }

        else
        {
            holder.weight.setText("");
        }

        if(wed.getRepetitions() != -1)
        {
            holder.text2.setText(wed.getRepetitions()+"");
        }

        else
        {
            holder.reps.setText("");
        }

        return v;
}

假设我有动态数量的子项,每个子项都有自己的编辑文本。我们如何创建并设置与子项计数相等的文本观察器?谢谢。 - yfsx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接