如何删除arraylist项目然后更新listview

时间:2012-06-28 18:50:28

标签: android listview android-listview

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);
}

}

我想从数组列表中删除项目。如你所见,我正在使用复选框。我第一次单击该复选框时,删除了正确的项目。第二次如果单击该复选框,应用程序会因索引超出范围而崩溃。如何从名为tasks的数组列表中删除项目并更新listview?

1 个答案:

答案 0 :(得分:4)

tasks数组中删除项目后,之后的所有项目都会获得一个新索引,以便您保存在持有者中并传递给{的所有position值{1}}错了。我想以这种方式做到这一点,你不能依赖于使用数组中的位置作为查找条目的方式。您需要使用对象本身并搜索数组以查找匹配对象。使用像

这样的东西
OnCheckedChangeListener

编辑:添加代码示例:

试试这个:

int arrayIndexOfThisTask = tasks.indexOf(objectThatIsInTheArray);

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

您的代码实际上有很多问题:

  1. 您没有正确使用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; } 模式。您从未使用ViewHolderViewHolder附加到View本身,并且在{{1}中给出了回收的视图时,您从未从setTag()检索ViewHolder }}。
  2. 如果View为非null,则只需返回它而不对其执行任何操作。这是错误的,因为适配器以任何方式回收视图,它可能会从位置6传递convertView并向位置1请求convertView。在这种情况下,您将刚刚返回{ {1}}表示位置6(不正确)。
  3. 我已将实际的View对象传递给View方法,而不是传递位置,我使用View来获取该对象的数组中的当前位置。
  4. 我希望这有用。