Android - Пользовательский адаптер ListView - Multi Selection удалить - Indexoutofbounds - почему?

У меня есть собственный ListView, использующий класс адаптера для расширения ArrayAdapter класса Item. У меня есть возможность переключаться между режимами выбора NONE, Single и Multi. Это все отлично работает. Сейчас я пытаюсь реализовать метод удаления элементов из списка (и адаптера) с множественным выбором в режиме множественного выбора. Однако я получаю исключения IndexOutOFBounds при выполнении одного из следующих действий; 1) удалить последний элемент в просмотре списка в режиме выбора ОДИН (Примечание: все, что осталось до последнего элемента, удаляется нормально) 2) В режиме выбора нескольких вариантов я снова не могу удалить последний элемент 3) снова в режиме множественного выбора я могу удалить отдельные выбранные элементы перед последним элементом, но 2 или более выбора снова приводят к ошибкам индекса за пределами границ.

Я добавил журнал отладки, чтобы показать удаляемую позицию, размер getCheckItemPositions () и счетчик цикла for (например, i) и, наконец, заголовок элемента удаляемого элемента. Если я закомментирую фактическую строку listadpter.remove (position), то вывод журнала, кажется, показывает, что все работает нормально, поэтому я теперь подозреваю, что проблема связана с методом getView класса моего адаптера. Но мой мозг истощен, и я застрял.

MainActivity.class - метод removeItems, вызываемый из объекта представления кнопки;

private void removeItems() {
    final SparseBooleanArray checkedItems = listView.getCheckedItemPositions();
    //final long[] checkedItemIds = listView.getCheckedItemIds();
    final int checkedItemsCount = checkedItems.size();

    Log.d("drp", "Adapter Count is: " + Integer.toString(mMyListViewAdapter.getCount()));
    if (checkedItems != null) {
        for (int i = checkedItemsCount-1; i >= 0 ; --i) {
            // This tells us the item position we are looking at
            // --
            final int position = checkedItems.keyAt(i);
            // This tells us the item status at the above position
            // --
            final boolean isChecked = checkedItems.valueAt(i);

            if (isChecked) {
                Item item = mMyListViewAdapter.getItem(position);
                Log.d("drp", "removing : " + Integer.toString(position) + " of " +Integer.toString(checkedItemsCount) + "-" + Integer.toString(i) + " - Title: " + mMyListViewAdapter.getItem(position).getTitle());
                mMyListViewAdapter.remove(item);

            }
        }
    }
}

Класс адаптера;

public class MyListViewAdapter extends ArrayAdapter<Item>  implements OnItemClickListener{

private LayoutInflater mInflator;

/**
 * This is my view holder for getView method so don't need to call
 * findViewById all the time which results in speed increase
 */
static class ViewHolder {

    public TextView txtTitle;
    public TextView txtDescription;
    public TextView txtSessionCount;
    public ImageView listThumbnailImage;
    public ImageView listStatusIndicatorImage;
    public InertCheckBox Checkbox;
}

/**
 * Constructor from a list of items
 */
public MyListViewAdapter(Context context, List<Item> items) {
    super(context, 0, items);
    mInflator = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // This is how you would determine if this particular item is checked
    // when the view gets created
    // --
    final ListView lv = (ListView) parent;
    final boolean isChecked = lv.isItemChecked(position);
    final int selectionMode = lv.getChoiceMode();

    // The item we want to get the view for
    // --
    Item item = getItem(position);

    // Re-use the view if possible (recycle)
    // --
    ViewHolder holder = null;
    if (convertView == null) {
        convertView = mInflator.inflate(R.layout.listview_row, null);
        holder = new ViewHolder();
        holder.txtTitle = (TextView) convertView.findViewById(R.id.title);
        holder.txtDescription = (TextView) convertView.findViewById(R.id.description);
        holder.txtSessionCount = (TextView) convertView.findViewById(R.id.session_count);
        holder.listThumbnailImage = (ImageView) convertView.findViewById(R.id.list_image);
        holder.listStatusIndicatorImage = (ImageView) convertView.findViewById(R.id.status);
        holder.Checkbox = (InertCheckBox) convertView.findViewById(R.id.inertCheckBox);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder)convertView.getTag();
    }
    holder.txtTitle.setText(item.getTitle());
    holder.txtDescription.setText(item.getDescription());
    holder.txtSessionCount.setText(item.getSessionCount());
    holder.listThumbnailImage.setImageBitmap((Bitmap) item.getThumbnailImage());        
    switch (selectionMode) {
    case ListView.CHOICE_MODE_NONE:
        holder.Checkbox.setVisibility(InertCheckBox.GONE);
        holder.listStatusIndicatorImage.setVisibility(ImageView.VISIBLE);
        holder.listStatusIndicatorImage.setImageBitmap((Bitmap) item.getListIndicatorImage());
        break;
    //case ListView.CHOICE_MODE_SINGLE: case ListView.CHOICE_MODE_MULTIPLE:
    default:
        holder.listStatusIndicatorImage.setVisibility(ImageView.GONE);
        holder.Checkbox.setVisibility(InertCheckBox.VISIBLE);
        holder.Checkbox.setButtonDrawable(R.drawable.checkbox);
        holder.Checkbox.setChecked(isChecked);
        break;
    }           


    return convertView;
}

@Override
public long getItemId(int position) {
    return getItem(position).getId();
}

@Override
public boolean hasStableIds() {
    return true;
}

А Item Class - первая половина;

public class Item implements Comparable<Item> {

private long id;
private String title;
private String description;
private String session_count;
private Bitmap listImage;
private Bitmap statusImage;

public Item(long id, String title, String description, String session_count, Bitmap listImage, Bitmap statusImage) {
    super();
    this.id = id;
    this.title = title;
    this.description = description;
    this.session_count = session_count;
    this.listImage = listImage;
    this.statusImage = statusImage;
}

public long getId() {
    return id;
}

public void setId(long id) {
    this.id = id;
}

public String getTitle() {
    return title;
}

Вот визуальная информация о моем удалении элемента отслеживания журнала отладки

07-23 22:59:14.910: D/drp(19104): Adapter Count is: 51
07-23 22:59:14.910: D/drp(19104): removing : 50 of 4-3 - Title: Test 50 - testing
07-23 22:59:14.910: D/drp(19104): removing : 49 of 4-2 - Title: Test 49 - testing
07-23 22:59:14.910: D/drp(19104): removing : 48 of 4-1 - Title: Test 48 - testing

Опять же, если я закомментирую & quot; mMyListViewAdapter.remove (item); & quot; Линия в MainActivity не вылетает, и журнал, кажется, указывает на ее работу как ожидалось. Может кто-нибудь увидеть мою ошибку, которая приводит к моему исключению Index Out Of Bounds?

Также я использую SDK 4.0.4 API 15.

Большое спасибо,

Павел.

Дополнение - полный вывод журнала

        07-25 00:21:53.235: D/AbsListView(25952): Get MotionRecognitionManager
        07-25 00:21:53.270: D/dalvikvm(25952): GC_CONCURRENT freed 89K, 3% free 13027K/13383K, paused 1ms+2ms
        07-25 00:21:53.430: D/dalvikvm(25952): GC_CONCURRENT freed 207K, 4% free 13232K/13703K, paused 3ms+2ms
        07-25 00:21:53.630: D/CLIPBOARD(25952): Hide Clipboard dialog at Starting input: finished by someone else... !
        07-25 00:21:54.930: D/dalvikvm(25952): GC_FOR_ALLOC freed 189K, 4% free 13331K/13767K, paused 10ms
        07-25 00:21:54.930: I/dalvikvm-heap(25952): Grow heap (frag case) to 13.610MB for 408976-byte allocation
        07-25 00:21:54.940: D/dalvikvm(25952): GC_FOR_ALLOC freed 6K, 4% free 13724K/14215K, paused 9ms
        07-25 00:21:54.950: D/dalvikvm(25952): GC_FOR_ALLOC freed 0K, 4% free 13724K/14215K, paused 9ms
        07-25 00:21:54.950: I/dalvikvm-heap(25952): Grow heap (frag case) to 13.994MB for 408976-byte allocation
        07-25 00:21:54.960: D/dalvikvm(25952): GC_FOR_ALLOC freed 0K, 4% free 14124K/14663K, paused 9ms
        07-25 00:21:54.970: D/dalvikvm(25952): GC_FOR_ALLOC freed 0K, 4% free 14124K/14663K, paused 9ms
        07-25 00:21:54.975: I/dalvikvm-heap(25952): Grow heap (frag case) to 14.384MB for 408976-byte allocation
        07-25 00:21:54.995: D/dalvikvm(25952): GC_CONCURRENT freed 0K, 4% free 14523K/15111K, paused 1ms+1ms
        07-25 00:21:55.005: D/dalvikvm(25952): GC_FOR_ALLOC freed 0K, 4% free 14523K/15111K, paused 9ms
        07-25 00:21:55.005: I/dalvikvm-heap(25952): Grow heap (frag case) to 14.774MB for 408976-byte allocation
        07-25 00:21:55.020: D/dalvikvm(25952): GC_FOR_ALLOC freed 0K, 5% free 14923K/15559K, paused 9ms
        07-25 00:21:55.030: D/dalvikvm(25952): GC_FOR_ALLOC freed <1K, 5% free 14923K/15559K, paused 9ms
        07-25 00:21:55.030: I/dalvikvm-heap(25952): Grow heap (frag case) to 15.165MB for 408976-byte allocation
        07-25 00:21:55.040: D/dalvikvm(25952): GC_FOR_ALLOC freed 0K, 5% free 15322K/16007K, paused 10ms
        07-25 00:21:55.055: D/dalvikvm(25952): GC_FOR_ALLOC freed 0K, 5% free 15722K/16455K, paused 9ms
        07-25 00:21:55.110: D/dalvikvm(25952): GC_FOR_ALLOC freed 157K, 5% free 16145K/16903K, paused 9ms
        07-25 00:21:56.565: E/SKIA(25952): FimgApiStretch:stretch failed
        07-25 00:21:56.690: E/SKIA(25952): FimgApiStretch:stretch failed
        07-25 00:21:56.710: E/SKIA(25952): FimgApiStretch:stretch failed
        07-25 00:22:00.545: D/drp(25952): Adapter Count is: 51
        07-25 00:22:00.545: D/drp(25952): removing : 49 of 2-2 - Title: Test 49 - testing
        07-25 00:22:00.545: D/drp(25952): removing : 48 of 2-1 - Title: Test 48 - testing
        07-25 00:22:00.545: D/drp(25952): removing : 47 of 2-0 - Title: Test 47 - testing
        07-25 00:22:00.550: D/AndroidRuntime(25952): Shutting down VM
        07-25 00:22:00.550: W/dalvikvm(25952): threadid=1: thread exiting with uncaught exception (group=0x40c6f1f8)
        07-25 00:22:00.560: E/AndroidRuntime(25952): FATAL EXCEPTION: main
        07-25 00:22:00.560: E/AndroidRuntime(25952): java.lang.IndexOutOfBoundsException: Invalid index 48, size is 48
        07-25 00:22:00.560: E/AndroidRuntime(25952):    at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
        07-25 00:22:00.560: E/AndroidRuntime(25952):    at java.util.ArrayList.get(ArrayList.java:304)
        07-25 00:22:00.560: E/AndroidRuntime(25952):    at android.widget.ArrayAdapter.getItem(ArrayAdapter.java:337)
        07-25 00:22:00.560: E/AndroidRuntime(25952):    at au.drp.mylistview.MyListViewAdapter.getItemId(MyListViewAdapter.java:107)
        07-25 00:22:00.560: E/AndroidRuntime(25952):    at android.widget.AbsListView.confirmCheckedPositionsById(AbsListView.java:5956)
        07-25 00:22:00.560: E/AndroidRuntime(25952):    at android.widget.AbsListView.handleDataChanged(AbsListView.java:5999)
        07-25 00:22:00.560: E/AndroidRuntime(25952):    at android.widget.ListView.layoutChildren(ListView.java:1535)
        07-25 00:22:00.560: E/AndroidRuntime(25952):    at android.widget.AbsListView.onLayout(AbsListView.java:2254)
        07-25 00:22:00.560: E/AndroidRuntime(25952):    at android.view.View.layout(View.java:11467)
        07-25 00:22:00.560: E/AndroidRuntime(25952):    at android.view.ViewGroup.layout(ViewGroup.java:4237)
        07-25 00:22:00.560: E/AndroidRuntime(25952):    at android.widget.RelativeLayout.onLayout(RelativeLayout.java:925)
        07-25 00:22:00.560: E/AndroidRuntime(25952):    at android.view.View.layout(View.java:11467)
        07-25 00:22:00.560: E/AndroidRuntime(25952):    at android.view.ViewGroup.layout(ViewGroup.java:4237)
        07-25 00:22:00.560: E/AndroidRuntime(25952):    at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
        07-25 00:22:00.560: E/AndroidRuntime(25952):    at android.view.View.layout(View.java:11467)
        07-25 00:22:00.560: E/AndroidRuntime(25952):    at android.view.ViewGroup.layout(ViewGroup.java:4237)
        07-25 00:22:00.560: E/AndroidRuntime(25952):    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1644)
        07-25 00:22:00.560: E/AndroidRuntime(25952):    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1502)
        07-25 00:22:00.560: E/AndroidRuntime(25952):    at android.widget.LinearLayout.onLayout(LinearLayout.java:1415)
        07-25 00:22:00.560: E/AndroidRuntime(25952):    at android.view.View.layout(View.java:11467)
        07-25 00:22:00.560: E/AndroidRuntime(25952):    at android.view.ViewGroup.layout(ViewGroup.java:4237)
        07-25 00:22:00.560: E/AndroidRuntime(25952):    at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
        07-25 00:22:00.560: E/AndroidRuntime(25952):    at android.view.View.layout(View.java:11467)
        07-25 00:22:00.560: E/AndroidRuntime(25952):    at android.view.ViewGroup.layout(ViewGroup.java:4237)
        07-25 00:22:00.560: E/AndroidRuntime(25952):    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1721)
        07-25 00:22:00.560: E/AndroidRuntime(25952):    at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2678)
        07-25 00:22:00.560: E/AndroidRuntime(25952):    at android.os.Handler.dispatchMessage(Handler.java:99)
        07-25 00:22:00.560: E/AndroidRuntime(25952):    at android.os.Looper.loop(Looper.java:137)
        07-25 00:22:00.560: E/AndroidRuntime(25952):    at android.app.ActivityThread.main(ActivityThread.java:4514)
        07-25 00:22:00.560: E/AndroidRuntime(25952):    at java.lang.reflect.Method.invokeNative(Native Method)
        07-25 00:22:00.560: E/AndroidRuntime(25952):    at java.lang.reflect.Method.invoke(Method.java:511)
        07-25 00:22:00.560: E/AndroidRuntime(25952):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:993)
        07-25 00:22:00.560: E/AndroidRuntime(25952):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:760)

Ответы на вопрос(6)

Ваш ответ на вопрос