2011-10-12 90 views
8

我有一个Android活动,其中有一个ListView绑定到自定义ArrayAdapter。 ListView的每一行都有两个EditText(数字)字段。Android - ListView中绑定到自定义ArrayAdapter的EditTexts - 跟踪更改

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

我通过将AfterTextChanged()事件的CustomTextWatcher附加到ArrayAdapter的getView()方法(传入EditText和ArrayAdapter的项目列表中的相应对象)中的每个EditText来记录更改,并且然后将该对象的匹配属性设置为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' - > ???????

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

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

回答

9

它看起来像一个自定义('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; 
} 
+0

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

相关问题