I've been struggling with the following problem for some days now. I have found many threads regarding this topic, but all are a little different or there was no solution.
For my project I created a custom ItemizedOverlay and added this to my MapView. If I now remove the last item of the list of items I get an IndexOutOfBoundsException claiming that the requested index is equal to the size of the ArrayList. I.e. index 2 size 2 or index 0 size 0. From what other topics have told me I have already tried the populate() and setLastFocusedIndex(-1) methods. These have solved other problems I had, but not this one. When removing other items from the list it works fine, the problem only seems to occur for the last item.
I get the following Logcat output:
01-24 16:11:08.091: E/AndroidRuntime(916): Uncaught handler: thread main exiting due to uncaught exception
01-24 16:11:08.101: E/AndroidRuntime(916): java.lang.IndexOutOfBoundsException: Invalid location 0, size is 0
01-24 16:11:08.101: E/AndroidRuntime(916): at java.util.ArrayList.get(ArrayList.java:341)
01-24 16:11:08.101: E/AndroidRuntime(916): at com.google.android.maps.ItemizedOverlay.getItem(ItemizedOverlay.java:419)
01-24 16:11:08.101: E/AndroidRuntime(916): at com.google.android.maps.ItemizedOverlay.focus(ItemizedOverlay.java:538)
01-24 16:11:08.101: E/AndroidRuntime(916): at com.google.android.maps.ItemizedOverlay.onTap(ItemizedOverlay.java:455)
01-24 16:11:08.101: E/AndroidRuntime(916): at com.google.android.maps.OverlayBundle.onTap(OverlayBundle.java:83)
01-24 16:11:08.101: E/AndroidRuntime(916): at com.google.android.maps.MapView$1.onSingleTapUp(MapView.java:346)
01-24 16:11:08.101: E/AndroidRuntime(916): at android.view.GestureDetector.onTouchEvent(GestureDetector.java:506)
01-24 16:11:08.101: E/AndroidRuntime(916): at com.google.android.maps.MapView.onTouchEvent(MapView.java:628)
01-24 16:11:08.101: E/AndroidRuntime(916): at android.view.View.dispatchTouchEvent(View.java:3709)
01-24 16:11:08.101: E/AndroidRuntime(916): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:852)
01-24 16:11:08.101: E/AndroidRuntime(916): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
01-24 16:11:08.101: E/AndroidRuntime(916): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
01-24 16:11:08.101: E/AndroidRuntime(916): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
01-24 16:11:08.101: E/AndroidRuntime(916): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
01-24 16:11:08.101: E/AndroidRuntime(916): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1659)
01-24 16:11:08.101: E/AndroidRuntime(916): at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1107)
01-24 16:11:08.101: E/AndroidRuntime(916): at android.app.Activity.dispatchTouchEvent(Activity.java:2061)
01-24 16:11:08.101: E/AndroidRuntime(916): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1643)
01-24 16:11:08.101: E/AndroidRuntime(916): at android.view.ViewRoot.handleMessage(ViewRoot.java:1691)
01-24 16:11:08.101: E/AndroidRuntime(916): at android.os.Handler.dispatchMessage(Handler.java:99)
01-24 16:11:08.101: E/AndroidRuntime(916): at android.os.Looper.loop(Looper.java:123)
01-24 16:11:08.101: E/AndroidRuntime(916): at android.app.ActivityThread.main(ActivityThread.java:4363)
01-24 16:11:08.101: E/AndroidRuntime(916): at java.lang.reflect.Method.invokeNative(Native Method)
01-24 16:11:08.101: E/AndroidRuntime(916): at java.lang.reflect.Method.invoke(Method.java:521)
01-24 16:11:08.101: E/AndroidRuntime(916): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
01-24 16:11:08.101: E/AndroidRuntime(916): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
01-24 16:11:08.101: E/AndroidRuntime(916): at dalvik.system.NativeStart.main(Native Method)
What bothers me about this is that it seems to be calling methods from the standard ItemizedOverlay. I have not added a normal ItemizedOverlay and I don't call super methods in my itemizedOverlay except in the constructor. Still the error seems to occur in a normal ItemizedOverlay, for which it would make sense that the ArrayList is empty.
I hope someone can point me in the right direction since I really feel stuck here. Thanks in advance!
Here is my code:
public class GameItemOverlay extends ItemizedOverlay<Item> {
private ArrayList<Item> mOverlays = new ArrayList<Item>();
public GameItemOverlay(Drawable defaultMarker) {
super(boundCenterBottom(defaultMarker));
setLastFocusedIndex(-1);
populate();
}
public void itemDataReady(){
mOverlays = GameSession.items;
setLastFocusedIndex(-1);
populate();
}
@Override
protected Item createItem(int i) {
return mOverlays.get(i);
}
@Override
public int size() {
return mOverlays.size();
}
@Override
protected boolean onTap(int i){
GameSession.remove(mOverlays.get(i).getID()); //Removes the item according to it's position
setLastFocusedIndex(-1);
populate();
return true;
}
}
It took me a while to figure the problem. I think the answer to this question is that
ItemizedOverlayis not intended to be used to manage (add and remove)OverlayItems. You can pretty much only addOverlayItems toItemizedOverlayand if you want to change any item, you need to recreateItemizedOverlay(not efficient). To solve this problem you need to manageItemizedOverlays (with just oneOverlayItem) in list ofOverlays instead ofOverlayItems inItemizedOverlay. Something like that: