我几天来一直在努力解决以下问题。我找到了很多关于这个主题的主题,但都有一些不同或者没有解决方案。
对于我的项目,我创建了一个自定义ItemizedOverlay
并将其添加到我的MapView
。如果我现在删除项目列表的最后一项,我会得到IndexOutOfBoundsException
声称请求的索引等于ArrayList
的大小。即索引2大小2或索引0大小0.从其他主题告诉我,我已经尝试了populate()
和setLastFocusedIndex(-1)
方法。这些已经解决了我遇到的其他问题,但没有解决这个问题。从列表中删除其他项目时,它可以正常工作,但问题似乎只发生在最后一项上。
我得到以下Logcat输出:
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)
令我烦恼的是,它似乎是从标准ItemizedOverlay
调用方法。我没有添加正常的ItemizedOverlay
,除了构造函数之外,我不会在我的itemizedOverlay
中调用超级方法。仍然错误似乎发生在正常的ItemizedOverlay
中,因此ArrayList
为空是有意义的。
我希望有人可以指出我正确的方向,因为我真的感到困在这里。提前谢谢!
这是我的代码:
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;
}
}
答案 0 :(得分:3)
我花了一段时间来解决这个问题。我认为这个问题的答案是ItemizedOverlay
无意用于管理(添加和删除)OverlayItem
。您几乎只能将OverlayItem
添加到ItemizedOverlay
,如果您想更改任何项目,则需要重新创建ItemizedOverlay
(效率不高)。要解决此问题,您需要在ItemizedOverlay
的{{1}} s而不是OverlayItem
的{{1}}列表中管理Overlay
s(只有一个OverlayItem
)。这样的事情:
ItemizedOverlay
答案 1 :(得分:1)
遇到同样的问题和解决方法。 当您在onTap方法中缩小OverlayItem列表时,看起来谷歌的代码上升(或下调)的代码会非常混乱。显然有一些索引没有更新(或过早更新) - 因此IOOBE。
我的解决方案基于以下事实:我的ItemizedOverlay子类中还有一个GestureDetector(我使用onSingleTapConfirmed()
将项目添加到我的地图中)。
ItemizedOverlay.onTap(int)
函数中保存刚刚点击的OverlayItem的索引,但不要修改列表(尚未)onSingleTapConfirmed()
中检查是否设置了'justTapped'变量。
setLastFocusedIndex(-1)
和populate()
以更新内部叠加层invalidate()
MapView重绘。希望这对任何人都有帮助!
答案 2 :(得分:1)
我遇到了同样的问题。在我的情况下,我扩展了ItemizedOverlay,而在里面 - 保留了一个OverlayItems数组。每次我平移或缩放地图时,我都会清除内部项目列表,添加新项目,然后调用填充。 (通过一些例子我发现了某处)。问题是基类 - ItemizedOverlay保持内部变量“lastFocusedIndex”。重新填充列表后,如果它没有重置 - 下次你决定点击地图中的某个位置 - 它首先决定从lastSelectedItem中移除焦点....现在 - 如果你的新列表包含的项目少于值lastSelectedItem - 然后它失败并出现此异常。
我的案例中的解决方案是 - 在清除OverlayItems的内部列表之后,还调用setLastFocusedIndex(-1) - 这可以确保重置所有内容。
关于对我调试它有用的一些注意事项: 1.从android-sdk中的maps.jar中反编译ItemizedOverlay - 没有帮助,因为这只是一个API / Stub jar,它不包含使用的实际类@ runtime 2.使用DDMS下载的system / framwork / com.google.android.maps.jar 3.使用dex2jar转换它,然后提取正确的类文件以进行反编译