1

私はここ数日、次の問題に苦しんでいます。このトピックに関する多くのスレッドを見つけましたが、すべてが少し異なっているか、解決策がありませんでした.

私のプロジェクトでは、カスタムを作成し、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;

    }
}
4

3 に答える 3

3

問題を理解するのにしばらく時間がかかりました。この質問に対する答えは、を管理 (追加および削除) するために使用することを意図していないItemizedOverlayということだと思います。s を追加することしかできず、アイテムを変更したい場合は、再作成する必要があります(効率的ではありません)。この問題を解決するには、の代わりにのリストで を(1 つだけ) を管理する必要があります。そんな感じ:OverlayItemOverlayItemItemizedOverlayItemizedOverlayItemizedOverlayOverlayItemOverlayOverlayItemItemizedOverlay

public class SomeActivity extends MapActivity {

    private SomeMapView mView;

    // Rest of the code ...

    private void sendRequest(GeoPoint point)
    {
        List<Overlay> mOverlays = mView.getOverlays();
        // Show red marker
        OverlayItem item    = new OverlayItem(point, "Hello", "world");   
        MarkerItemizedOverlay itemOverlay   = new MarkerItemizedOverlay(drawable, mView);
        itemOverlay.addOverlay(item);
        mOverlays.add(itemOverlay);
    }
}

public class MarkerItemizedOverlay extends ItemizedOverlay<OverlayItem> {

    private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
    MapView mView;

    // Rest of the code ...

    @Override
    protected boolean onTap(int index) {
        List<Overlay> mOverlays = mView.getOverlays();
        mOverlays.remove(this);
    }
}
于 2012-04-28T14:31:04.413 に答える
1

私も同じ問題を抱えていました。私の場合、ItemizedOverlay を拡張し、内部で OverlayItems の配列を保持していました。マップをパンまたはズームするたびに、アイテムの内部リストをクリアし、新しいアイテムを追加してから populate を呼び出していました。(いくつかの例では、どこかで見つけました)。問題は、基本クラスの ItemizedOverlay が内部変数「lastFocusedIndex」を保持していることでした。リストを再作成した後、リセットされていない場合 - 次にマップ内のどこかをクリックすることを決定したとき - 最初に lastSelectedItem からフォーカスを削除することを決定しました....そして今 - 新しいリストに値よりも少ないアイテムが含まれている場合lastSelectedItem の - この例外で失敗します。

私の場合の解決策は、OverlayItems の内部リストをクリアした後、setLastFocusedIndex(-1) も呼び出すことでした。これにより、すべてが確実にリセットされます。

デバッグするのに何が役立ったかについてのいくつかのメモ: 2. DDMS を使用してダウンロードした system/framwork/com.google.android.maps.jar 3. dex2jar を使用して変換し、正しいクラス ファイルを抽出して逆コンパイルします

于 2013-02-23T03:32:06.650 に答える
1

同じ問題と回避策があります。onTap メソッドで OverlayItem リストを縮小すると、呼び出しチェーンがひどく混乱する Google のコードのようです。どうやら、更新されていない (または更新が早す​​ぎる) インデックスがいくつかあるようです。したがって、IOOBE です。

私のソリューションは、ItemizedOverlay サブクラスにも GestureDetector があるという事実に基づいています (onSingleTapConfirmed()マップにアイテムを追加するために を使用しています)。

  • 関数でItemizedOverlay.onTap(int)、タップしたばかりの OverlayItem のインデックスを保存しますが、リストは (まだ) 変更しないでください
  • onSingleTapConfirmed()「justTapped」変数が設定されているかどうか を確認します。
    • その場合は、リストから削除してください
    • 呼び出しsetLastFocusedIndex(-1)populate()オーバーレイを内部的に更新する
    • invalidate()再描画する MapView。
  • (オプション) 作業中のコードを祝うためにちょっとしたハッピー ダンスをします。

これが誰にも役立つことを願っています!

于 2012-07-03T16:25:24.767 に答える