Android IndexOutOfBoundsException:索引0无效,大小为0

时间:2016-02-21 02:32:22

标签: java android listview

是的,我相信有很多问题要问这个错误,但我认为它与以下内容有关,如下所示。

我有3个ListView mNote1, mNote2, mNote3,它们都已通过registerForContextMenu();传递。然后是onCreateContextMenu方法:

请注意课程活动的顶部有private static final int MENU_DELETE_ID = 1004; private int currentNoteId;

public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {

        AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
        currentNoteId = (int) info.id;

        menu.add(0, MENU_DELETE_ID, 0, "Delete");

    }

然后是onContextItemSelected方法:

@Override
    public boolean onContextItemSelected(MenuItem item) {

        if(item.getItemId() == MENU_DELETE_ID){
            NoteItem note = noteList.get(currentNoteId);
            NoteItem note1 = noteList1.get(currentNoteId);
            NoteItem note2 = noteList2.get(currentNoteId);
            datasource.remove(note);
            datasource1.remove(note1);
            datasource2.remove(note2);
            refreshDisplay(1001);
            refreshDisplay(1002);
            refreshDisplay(1003);

        }

        return super.onContextItemSelected(item);
    }

我相信,这些创造了"删除"按住ListView上的音符时选项,然后在选择删除选项时删除音符。我相信onContextItemSelected方法就是错误所在。

在应用程序上,我在第一个ListView中创建了一个注释,当应用程序崩溃时我无法将其删除。我可以在多个ListView中制作多个音符,但我无法删除它们。

NoteDataSource文件如下所示,这将创建datasource1,datasource2等

public class NoteDataSource {

    private SharedPreferences notePrefs;

    public NoteDataSource(Context context, String PREFKEY){
        notePrefs = context.getSharedPreferences(PREFKEY, Context.MODE_PRIVATE);
    }

    public List<NoteItem> findAll(){

        Map<String, ?> noteMap = notePrefs.getAll();

        SortedSet<String> keys = new TreeSet<String>(noteMap.keySet());

        List<NoteItem> noteList = new ArrayList<NoteItem>();

        for (String key:keys) {
            NoteItem note = new NoteItem();
            note.setKey(key);
            note.setText((String) noteMap.get(key));
            noteList.add(note);
        }

        return noteList;

    }

    public boolean remove(NoteItem item){

        if (notePrefs.contains(item.getKey())){
            SharedPreferences.Editor editor = notePrefs.edit();
            editor.remove(item.getKey());
            editor.apply();
        }

        return true;
    }
    public boolean update(MealItem item){

        SharedPreferences.Editor editor = mealPrefs.edit();
        editor.putString(item.getKey(), item.getText());
        editor.apply();

        return true;
    }

}

使用datasource在onCreate方法中创建datasource = new NoteDataSource(this, "note1");,并在refreshDisplay方法中引用它们:注意,private ArrayAdapter<MealItem> adapter; 1和2在类顶部初始化

private void refreshDisplay(int code) {
    notesList = datasource.findAll();
    notesList1 = datasource1.findAll();
    notesList2 = datasource2.findAll();

    if(code == 1001){
        adapter = new ArrayAdapter<NoteItem>(this, R.layout.list_item_layout, notesList);
        mNote1.setAdapter(adapter);
    }else if (code == 1002){
        adapter = new ArrayAdapter<NoteItem>(this, R.layout.list_item_layout, notesList1);
        mNote2.setAdapter(adapter);
    }else if(code == 1003){
        adapter = new ArrayAdapter<NoteItem>(this, R.layout.list_item_layout, notesList2);
        mNote3.setAdapter(adapter);
    }
}

notesList初始化在班级的顶部,List<NoteItem> notesList;有3个theese,notesList,notesList1和notesList2

我不确定错误来自哪里,但我知道当我尝试删除笔记时,应用程序崩溃并且我制作的笔记仍在那里。

错误日志显示

java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
                                                                            at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
                                                                            at java.util.ArrayList.get(ArrayList.java:308)
                                                                            at com.example.notesapp.mainact.onContextItemSelected(MainAct.java:166)
                                                                            at android.app.Activity.onMenuItemSelected(Activity.java:2928)

我认为我应该做的是确定我选择的音符列表视图所在的数据源,因为目前我正在将它们全部删除,如上所示onContextItemSelected

NoteItem note = noteList.get(currentNoteId);
                NoteItem note1 = noteList1.get(currentNoteId);
                NoteItem note2 = noteList2.get(currentNoteId);
                datasource.remove(note);
                datasource1.remove(note1);
                datasource2.remove(note2);
                refreshDisplay(1001);
                refreshDisplay(1002);
                refreshDisplay(1003);

任何帮助将不胜感激。谢谢!

编辑:

我一直在关注Lynda.com构建Android笔记应用程序(2013)的教程。我创建了我的应用程序,因此它有3个ListView而不是一个。用户可以根据他们按下的按钮向列表视图添加注释。因此,如果他们按下button1然后输入文本并回击它将出现在listview1等等。

如果我要有一个ListView,我的程序就可以正常运行,因为我只能从第一个ListView删除备注。第一个ListView对应datasourcenotesList ,而第二个和第三个ListView分别对应datasource1 datasource2notesList1notesList2

要删除记事,请按住ListView记事,然后单击“删除”。这适用于第一个ListView但不是第二个和第三个,应用程序崩溃。错误日志显示。以下方法是我在按住时创建删除按钮以及删除按钮的方法。

请注意课程活动的顶部有private static final int MENU_DELETE_ID = 1004; private int currentNoteId;

public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {

        AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
        currentNoteId = (int) info.id;

        menu.add(0, MENU_DELETE_ID, 0, "Delete");

    }

然后是onContextItemSelected方法:

@Override
    public boolean onContextItemSelected(MenuItem item) {

        if(item.getItemId() == MENU_DELETE_ID){
            NoteItem note = noteList.get(currentNoteId);
            NoteItem note1 = noteList1.get(currentNoteId);
            NoteItem note2 = noteList2.get(currentNoteId);
            datasource.remove(note);
            datasource1.remove(note1);
            datasource2.remove(note2);
            refreshDisplay(1001);
            refreshDisplay(1002);
            refreshDisplay(1003);

        }

        return super.onContextItemSelected(item);
    }

应用程序崩溃在NoteItem note1 = noteList1.get(currentNoteId);我不确定从哪里开始。

编辑2:

好的,所以当我选择删除而不是删除它时,我对currentNoteId进行了烘烤。第一个音符是0,第二个是1,等等。所以我相信当我调用notesList.get(currentNoteId)时它从该数组中获取索引。

我想我需要某种方式来表示我从中选择了哪个ListView,这需要位于onCreateContextMenu中,这显示在我的问题的最顶层。

1 个答案:

答案 0 :(得分:0)

在我的onCreateContextMenu方法中,我添加了以下行:viewNoteId = v.getId();,它获得了创建上下文菜单的ListView的ID。

然后我在onContextItemSelected方法中添加了一个switch case元素,如下所示:

    if (item.getItemId() == MENU_DELETE_ID){
        switch (viewNoteId){
            case R.id.listMonB:
                NoteItem note = notesList.get(currentNoteId);
                datasource.remove(note);
                refreshDisplay(1001);
                break;
            case R.id.listMonL:
                NoteItem note1 = notesList1.get(currentNoteId);
                datasource1.remove(note1);
                refreshDisplay(1002);
                break;
            case R.id.listMonD:
                NoteItem note2 = notesList2.get(currentNoteId);
                datasource2.remove(note2);
                refreshDisplay(1003);
                break;

        }
    }

它现在有效!