Pages

2011年6月4日土曜日

ItemizeOverlayでハマったこと。

AndroidでMaps系アプリを開発しててハマったこと。





MapViewの上に画像などを表示させたければ、Overlayを継承したクラスを利用するのが一般的。

Overlayでは表示する画像の位置指定は画面のxy座標で指定する。

地図上の位置に対して複数の画像を表示したければ、GeoPoint(latとlng)で指定できるItemizeOverlayを継承したクラスを使うといい。

こんな感じ。


public class MyItemizeOverlay extends ItemizeOverlay{
ArrayList itemList = new itemList;

public MyItemizeOverlay(Drawable drawable) {
super(drawable);
}

@Override
protected OverlayItem createItem(int i) {
Item item = itemList.get(i)
OverlayItem tmp
= new OverlayItem (i.getGeoPoint(), i.getName(), "");

return tmp;
}

@Override
public int size() {
return itemList.size();
}
}


必ずOverrideしないといけないのは#createItemと#sizeの2つ。

#sizeは表示するアイテムの数を返すように、#createItemは渡されたindex(0~[#sizeでreturnしたint値])から表示するアイテム(OverlayItem)を生成して返すようにする。


あとやるべきことは、表示するアイテムの数などに変更があった場合、描画する前に#poplateを呼び出す必要がある。




と、公式リファレンスをみる限りで読み取れるのはここまで。




で、こっからがハマった。恐らくバグ。

表示するアイテムに変更があった場合、それを表示する(MapView#indvalidateの呼び出しやドラッグによる再描画)前に、必ず#setLastFocusedIndex(-1)と#poplate()を呼び出す必要がある。

呼び出さないと、Array Index Out of Bounds Exeption errorが発生する。

どうやら、表示アイテム変更時にアイテムの管理をしているインデックスが狂うらしい。



さらに、ItemizeOverlayを複数用意して使う場合、1つのItemizeOverlayのアイテムに変更があった場合でも、その他のItemizeOverlayにも上記の処理をしてやらなければならない。

表示する際に、内部ではMapViewとItemizeOverlayを統合するような仕様になってて、そこで上手くインデックスの初期化がされなくなってるのだろうか。

0 コメント:

コメントを投稿

Blogger Syntax Highliter