1

私は Android/Java を学んListViewでおり、データベースに接続しており、simple_list_item_multiple_choice各行にチェック ボックスが含まれています。ユーザーが 1 つのチェック ボックスをオンにして削除ボタンを押すと、その行が削除され、ListViewそれに応じて更新されます。ただし、ユーザーが複数の行をチェックすると、アプリが壊れます。

ListViewアタッチされたデータベースから削除するためにで複数の行を選択すると、アプリが壊れるのはなぜですか?

public class ListViewDisplayNumbers extends ListActivity {
public void DeleteNumber() {

    NumbersDataSource datasource = new NumbersDataSource(this);
    datasource.open();

    ListView listView = (ListView) findViewById(android.R.id.numberlist);
    SparseBooleanArray checked = listView.getCheckedItemPositions();

    List<Number> values = datasource.getAllNumbers();
    ArrayAdapter<Number> adapter = new ArrayAdapter<Number>(this, android.R.layout.simple_list_item_multiple_choice, values);

    for (int i = 0; i < checked.size(); i++) {
        int position = checked.keyAt(i);
        if (checked.valueAt(i))
            datasource.deleteNumber(adapter.getItem(position));
            adapter.remove(adapter.getItem(position)); //breaks on the last one of a multiple
    }

    adapter.notifyDataSetChanged();
    setListAdapter(adapter);
    datasource.close();
}

丸太の猫:

01-25 12:26:06.236: E/AndroidRuntime(7140): FATAL EXCEPTION: main
01-25 12:26:06.236: E/AndroidRuntime(7140): java.lang.IndexOutOfBoundsException: Invalid index 3, size is 2
01-25 12:26:06.236: E/AndroidRuntime(7140):     at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
01-25 12:26:06.236: E/AndroidRuntime(7140):     at java.util.ArrayList.get(ArrayList.java:304)
01-25 12:26:06.236: E/AndroidRuntime(7140):     at android.widget.ArrayAdapter.getItem(ArrayAdapter.java:337)
01-25 12:26:06.236: E/AndroidRuntime(7140):     at com.example.hw.ListViewDisplayNumbers.deleteNumber(ListViewDisplayNumbers.java:103)
01-25 12:26:06.236: E/AndroidRuntime(7140):     at com.example.hw.ListViewDisplayNumbers.onOptionsItemSelected(ListViewDisplayNumbers.java:128)
01-25 12:26:06.236: E/AndroidRuntime(7140):     at android.app.Activity.onMenuItemSelected(Activity.java:2507)
01-25 12:26:06.236: E/AndroidRuntime(7140):     at com.android.internal.policy.impl.PhoneWindow.onMenuItemSelected(PhoneWindow.java:982)
01-25 12:26:06.236: E/AndroidRuntime(7140):     at com.android.internal.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:735)
01-25 12:26:06.236: E/AndroidRuntime(7140):     at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:149)
01-25 12:26:06.236: E/AndroidRuntime(7140):     at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:874)
01-25 12:26:06.236: E/AndroidRuntime(7140):     at com.android.internal.view.menu.ListMenuPresenter.onItemClick(ListMenuPresenter.java:175)
01-25 12:26:06.236: E/AndroidRuntime(7140):     at android.widget.AdapterView.performItemClick(AdapterView.java:292)
01-25 12:26:06.236: E/AndroidRuntime(7140):     at android.widget.AbsListView.performItemClick(AbsListView.java:1393)
01-25 12:26:06.236: E/AndroidRuntime(7140):     at android.widget.AbsListView$PerformClick.run(AbsListView.java:3022)
01-25 12:26:06.236: E/AndroidRuntime(7140):     at android.widget.AbsListView$1.run(AbsListView.java:3817)
01-25 12:26:06.236: E/AndroidRuntime(7140):     at android.os.Handler.handleCallback(Handler.java:605)
01-25 12:26:06.236: E/AndroidRuntime(7140):     at android.os.Handler.dispatchMessage(Handler.java:92)
01-25 12:26:06.236: E/AndroidRuntime(7140):     at android.os.Looper.loop(Looper.java:137)
01-25 12:26:06.236: E/AndroidRuntime(7140):     at android.app.ActivityThread.main(ActivityThread.java:4517)
01-25 12:26:06.236: E/AndroidRuntime(7140):     at java.lang.reflect.Method.invokeNative(Native Method)
01-25 12:26:06.236: E/AndroidRuntime(7140):     at java.lang.reflect.Method.invoke(Method.java:511)
01-25 12:26:06.236: E/AndroidRuntime(7140):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:980)
01-25 12:26:06.236: E/AndroidRuntime(7140):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:747)
01-25 12:26:06.236: E/AndroidRuntime(7140):     at dalvik.system.NativeStart.main(Native Method)
4

1 に答える 1

1

これを逆方向に実行してみてください

for (int i = checked.size()-1; i >=0;i--) {
    int position = checked.keyAt(i);
    if (checked.valueAt(i)){
        datasource.deleteNumber(adapter.getItem(position));
        adapter.remove(adapter.getItem(position)); //breaks on the last one of a multiple
     }
}

理論的根拠:同様の問題があり、逆方向に実行することを推奨するこのSOの質問に出くわしました。ただし、前に進むと削除するとインデックスが台無しになる可能性があるため、逆に進むとリストを変更するときに何も影響を与えないはずです。

ifああ、そして私はあなたが両方のアダプタステートメントを1つのブロックに入れたいと思ったかもしれないことに気づきました。

于 2013-01-25T20:35:20.423 に答える