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

}

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

4

1 回答 1

4

从数组中删除一个项目tasks后,之后的所有项目都会获得一个新索引,因此position您保存在持有者中并传递给的所有值OnCheckedChangeListener都是错误的。如果你想这样做,你不能依赖使用数组中的位置作为查找条目的方式。您需要使用对象本身并搜索数组以找到匹配的对象。使用类似的东西

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正确使用该模式。您从未通过 using将其附加ViewHolderView自身,setTag()并且您从未ViewHolder在.ViewconvertView
  2. 如果convertView是非空的,你只是返回它而不用它做任何事情。这是错误的,因为适配器会以任何它想要的方式回收视图,并且它可能会View从位置 6 传递给您并要求View位置 1。在这种情况下,您将刚刚返回View位置 6(这是不正确的)。
  3. 我已经将实际Task对象传递给onCheckChanged()方法而不是传递位置,并且我已经习惯于indexOf()获取该对象在数组中的当前位置。

我希望这是有帮助的。

于 2012-06-28T19:12:45.310 回答