Yes, I believe that there are many questions asking about this error, however I believe it relates to the following, shown below.
I have 3 ListViews mNote1, mNote2, mNote3
and they have all been passed through registerForContextMenu();
. Then there is the onCreateContextMenu
method:
please note at the top of the class activity there is, 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");
}
and then the onContextItemSelected
method:
@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);
}
These, I believe, create the "Delete" option when the note on the ListView is held down and then the note is deleted when the delete option is selected. I believe in the onContextItemSelected
method is where the error lies.
On the app, I create a note in the first ListView and I am not able to delete it as the app crashes. I can make make multiple notes in multiple ListViews but I am unable to delete them.
The NoteDataSource file is shown below, this creates the datasource1, datasource2, etc
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;
}
}
The datasource
s are created in the onCreate method with datasource = new NoteDataSource(this, "note1");
and they are referenced in refreshDisplay method: Note, private ArrayAdapter<MealItem> adapter;
1 and 2 are initialized at the top of the class
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);
}
}
The notesList
are initialized at the top of the class, List<NoteItem> notesList;
there are 3 of theese, notesList, notesList1 and notesList2
I'm not sure where the error is from, but I know that it is when I try to delete a note the app crashes and the notes I made are still there.
The error log says
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)
What I think I am supposed to do is determine which datasource the note listview I have selected is in, as currently I am removing them all like this which is shown above in 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);
any help would be greatly appreciated. thank you!
EDIT:
I have been following along with the tutorial on Lynda.com Building a Note-Taking App for Android (2013). I have created my app so it has 3 ListViews instead of one. The user is able to add notes to the a listview depending on what button they press. So if they press button1 and then enter the text and hit back it would appear on listview1, etc etc.
If I was to have one ListView, my program would work as I can only delete notes from the first ListView. The first ListView corresponds with datasource
, and notesList
, whereas the second and third ListView correspond with datasource1
datasource2
, notesList1
, notesList2
respectively.
To delete a note, you hold the ListView note down and then click delete. This works on the first ListView but not the second and third, the app crashes. The error log shows that. The following methods are the ones I use to create the delete button when held down and also to delete it.
please note at the top of the class activity there is, 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");
}
and then the onContextItemSelected
method:
@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);
}
The app crashes at NoteItem note1 = noteList1.get(currentNoteId); and I am unsure on where to go from here.
EDIT 2:
Ok, so I Toasted the currentNoteId
when I selected delete instead of deleting it. The first note was 0 and the second 1, etc. So I believe when I call notesList.get(currentNoteId) its getting the index from that array.
I guess I need some sort of way to signify which ListView I have selected it from, which would need to be in onCreateContextMenu
which is shown at the very top of my question.