Android - ListView 中的 EditTexts 绑定到自定义 ArrayAdapter - 跟踪更改

Posted

技术标签:

【中文标题】Android - ListView 中的 EditTexts 绑定到自定义 ArrayAdapter - 跟踪更改【英文标题】:Android - EditTexts within ListView bound to Custom ArrayAdapter - keeping track of changes 【发布时间】:2011-12-05 20:41:21 【问题描述】:

我有一个 android 活动,其中我有一个绑定到自定义 ArrayAdapter 的 ListView。 ListView 的每一行都有两个 EditText(数字)字段。

ArrayAdapter 最初是从 SQLite DB 填充的。但是,用户可以在 ListView 的末尾添加一行,或者(通过长按一行)删除 ListView 中的任何行。当他们点击“保存”按钮时,他们的更改会被保留。

我正在跟踪所做的更改,方法是将 AfterTextChanged() 事件的 CustomTextWatcher 附加到 ArrayAdapter 的 getView() 方法中的每个 EditText(传入 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” 单击“更多”-> 在末尾添加一个(空)行。现在有 4 行。 删除最后一行->显示的 3 行,但现在第 2 行和第 3 行显示 '5'、'6'->???????

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

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

【问题讨论】:

【参考方案1】:

看起来我需要一个自定义('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;

【讨论】:

可以说我有动态数量的孩子,所有孩子都有自己的编辑文本。我们如何创建和设置文本观察者等于孩子数?谢谢

以上是关于Android - ListView 中的 EditTexts 绑定到自定义 ArrayAdapter - 跟踪更改的主要内容,如果未能解决你的问题,请参考以下文章

ListView 中的 Android Activity 转换

android中的listview正常和悬停背景样式

更改 ListView 中的字体大小 - Android/Eclipse

Android中的倒置ListView?

Android:将数据库中的数据绑定到 ListView 中的 CheckBox?

Android 应用中的动态 ListView