2012-06-28 77 views
0
ListView listView; 
Activity activity; 
public ArrayList<Tasks> tasks; 
View v; 

public TaskAdapter(Activity activity, ArrayList<Tasks> tasks) 
{ 
    super(activity, R.layout.presenterlayout, tasks); 
    this.activity = activity; 
    this.tasks = tasks; 
} 

static class ViewHolder { 
    public TextView taskTitleTextView; 
    public TextView taskDescriptionTextView; 
    public TextView taskDueTimeTextView; 
    public CheckBox checkBox; 
} 

public View getView(final int position, View convertView, ViewGroup parent) { 
    final ViewHolder holder; 
    v = convertView; 
    if (v == null) { 
     LayoutInflater inflator = activity.getLayoutInflater(); 
     v = inflator.inflate(R.layout.presenterlayout, null, false); 
     listView = (ListView) v.findViewById(R.id.listView); 
     holder = new ViewHolder(); 
     holder.taskTitleTextView = (TextView)  v.findViewById(R.id.taskTitleTextView); 
     holder.taskDescriptionTextView = (TextView) v.findViewById(R.id.taskDescriptionTextView); 
     holder.taskDueTimeTextView = (TextView) v.findViewById(R.id.taskDueTimeTextView); 
     holder.checkBox = (CheckBox) v.findViewById(R.id.checkBox); 
     holder.taskTitleTextView.setText(tasks.get(position).getTasksTitleString()); 
     holder.taskDescriptionTextView.setText(tasks.get(position).getTasksDescriptionString()); 
     holder.taskDueTimeTextView.setText(tasks.get(position).getTasksDueTimeString()); 
     holder.checkBox.setId(position); 
     holder.checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() { 

      @Override 
      public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
       if(holder.checkBox.isChecked()) 
       { 
        System.out.println("postion: " + position); 
        if(tasks.get(position).isTasksCompleted().equals("true")) 
        { 
         tasks.get(position).setTasksCompleted("false");       
        } 
        else if(tasks.get(position).isTasksCompleted().equals("false")) 
        { 
         tasks.get(position).setTasksCompleted("true");       
        } 
        updateThisTask(tasks.get(position)); 
        tasks.remove(position); 
        notifyDataSetChanged(); 
       } 
      } 
     }); 
    } 
    else { 
     v = convertView; 
    } 
    return v; 
} 

private void updateThisTask(Tasks tasks) { 
    DBAdapter dbAdapter = new DBAdapter(getContext()); 
    int id = dbAdapter.getID(tasks); 
    dbAdapter.updateTask(tasks, id); 
} 

} 

我想从数组列表中删除项目。正如你所看到的,我正在使用复选框。我第一次点击复选框时,正确的项目被删除。第二次,如果我点击复选框,由于索引超出范围,应用程序崩溃。我如何从数组列表中删除一个称为任务的项目并更新列表视图?如何删除ArrayList项目,然后更新列表视图

+0

您的适配器是baseAdapter/ArrayAdapter? – rajpara

+0

向我们展示您的LogCat请 –

回答

4

一旦你从tasks数组中删除一个项目,毕竟该项目得到一个新的指数,因此所有你已经保存在持有人,并传递到OnCheckedChangeListener是错误的position值。我想你这样做,你不能依赖数组中的位置作为查找条目的方式。您需要使用对象本身并搜索数组以查找匹配的对象。使用类似

int arrayIndexOfThisTask = tasks.indexOf(objectThatIsInTheArray); 

编辑:添加代码示例:

试试这个:

public View getView(int position, View convertView, ViewGroup parent) { 
    final ViewHolder holder; 
    v = convertView; 
    if (v == null) { 
     LayoutInflater inflator = activity.getLayoutInflater(); 
     v = inflator.inflate(R.layout.presenterlayout, null, false); 
     listView = (ListView) v.findViewById(R.id.listView); 
     holder = new ViewHolder(); 
     v.setTag(holder); // Attach the holder to the view so we can find it again 
     holder.taskTitleTextView = (TextView)  v.findViewById(R.id.taskTitleTextView); 
     holder.taskDescriptionTextView = (TextView) v.findViewById(R.id.taskDescriptionTextView); 
     holder.taskDueTimeTextView = (TextView) v.findViewById(R.id.taskDueTimeTextView); 
     holder.checkBox = (CheckBox) v.findViewById(R.id.checkBox); 
    } else { 
     // Get the ViewHolder from the recycled view 
     holder = (ViewHolder)v.getTag(); 
    } 
    // Get the task at this position in the array 
    final Task task = tasks.get(position); 

    holder.taskTitleTextView.setText(task.getTasksTitleString()); 
    holder.taskDescriptionTextView.setText(task.getTasksDescriptionString()); 
    holder.taskDueTimeTextView.setText(task.getTasksDueTimeString()); 
    holder.checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() { 
     @Override 
     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
      if(holder.checkBox.isChecked()) 
      { 
       // Try to find the position in the array for this object (it may already have been removed) 
       int position = tasks.indexOf(task); 
       System.out.println("postion: " + position); 
       // If this object is no longer in the array, just ignore this action 
       if (position >= 0) { 
        if(tasks.get(position).isTasksCompleted().equals("true")) 
        { 
         tasks.get(position).setTasksCompleted("false");       
        } 
        else if(tasks.get(position).isTasksCompleted().equals("false")) 
        { 
         tasks.get(position).setTasksCompleted("true");       
        } 
        updateThisTask(tasks.get(position)); 
        tasks.remove(position); 
        notifyDataSetChanged(); 
       } 
      } 
     } 
    }); 
    return v; 
} 

我可能没有一切完全正确,但你应该明白我的意思。

实际上有很多事情你的代码错误:

  1. 你没有正确使用ViewHolder模式。您从未使用setTag()ViewHolder附加到View本身,并且在convertView中给出再循环视图时,您从未从中检索到ViewHolder
  2. 如果convertView非空,您只是将它返回而不做任何事情。这是错误的,因为适配器以任何想要的方式回收视图,并且它可能会从位置6向您传递View,并要求位置1请求View。在这种情况下,您将刚刚返回位置6的View(这不是正确)。
  3. 我已将实际的Task对象传递给onCheckChanged()方法,而不是传递位置,我使用indexOf()来获取该对象的数组中的当前位置。

我希望这会有帮助。

+0

这不可能,因为我需要某种索引才能从数组列表中获取项目。 –

+0

增加了代码示例和其他一些观察。玩的开心。 –

+0

非常感谢,这些肯定是好的一点。 –

相关问题