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

}

I want to remove item from the array list. As you can see I am using checkbox. The first time I click the checkbox, correct item is removed. The second time if I click the checkbox, the application crashes due to index out of bounds. How can I remove an item from the array list called tasks and update the listview?

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パターンを正しく使用していませんでした。を使用して をそれ自体にアタッチしたことはViewHolderありません。ViewsetTag()ViewHolderViewconvertView
  2. が null 以外の場合convertViewは、何もせずにそれを返しました。これは間違っています。なぜなら、アダプターは好きなようにビューをリサイクルし、from 6 を渡してView位置View1 を要求する可能性があるためです。この場合View、位置 6 を返すだけです (これは正しくありません)。
  3. 位置を渡す代わりに実際のTaskオブジェクトをメソッドに渡し、そのオブジェクトの配列内の現在の位置を取得していました。onCheckChanged()indexOf()

これがお役に立てば幸いです。

于 2012-06-28T19:12:45.310 に答える