2010年10月26日火曜日

タッチイベントはMapViewとItemizedOverlayのどちらにまず伝わるのか

Android+Google MAP APIでタッチイベントを処理する時のイベントの流れを確認する。
使ったのは以下のクラス。

・MapDemoActivityクラス
MapActivityを継承したクラス。実行クラス。

・CusomizedMapViewクラス
MapViewを継承したクラス。MapDemoActivityのContentViewとして設定。

・GeoItemizedOverlayクラス
ItemizedOverlayを継承したクラス。


これらのクラスは、下から積み上げると以下のような階層関係にある。

GeoItemizedOverlay
|
CusomizedMapView
|
MapDemoActivity


・検証

ディバイスの画面にタッチしたときには、onTouchEvent(MotionEvent event)が呼び出される。

MapViewを使ったときは、Activityに記述したonTouchEventではなくMapView側のonTouchEventが呼び出されることは、前の記事に書いた。

では、MapViewにItemizedOverlayが追加されているときは、タッチイベントはMapViewとItemizedOverlayのどちらにまず伝わるのか。

public class MapDemoActivity extends MapActivity {
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  /** マップビュー作成 */
  CustomizedMapView mapView = (CustomizedMapView) findViewById(R.id.mapview);

  Drawable drawable = this.getResources().getDrawable(R.drawable.star);
  GeoItemizedOverlay geoOverlay = new GeoItemizedOverlay(drawable, this);

  /** オーバーレイをマップに追加 */
  List<Overlay> mapOverlays = mapView.getOverlays();
  mapOverlays.add(geoOverlay);
 }
}
public class CustomizedMapView extends MapView {
 @Override
 public boolean onTouchEvent(MotionEvent event) {
  Log.i("onTouchEvent", "CustomizedMapView.onTouchEvent");
  return super.onTouchEvent(event);
 }
}
public class GeoItemizedOverlay extends ItemizedOverlay<OverlayItem> {
 @Override
 public boolean onTouchEvent(MotionEvent event, MapView mapView) {
  Log.i("onTouchEvent", "GeoItemizedOverlay.onTouchEvent");
  return super.onTouchEvent(event, mapView);
 }
}

試してところ、ItemizedOverlayよりも先にMapViewへタッチイベントが伝わることが分かった。
10-26 13:29:55.577: INFO/MapDemo(4253): CustomizedMapView.onTouchEvent
10-26 13:29:55.577: INFO/MapDemo(4253): GeoItemizedOverlay.onTouchEvent

上記のクラスで言うと、

CustomizedMapView→GeoItemizedOverlay

の順番だ。


・結論

MapView側に記述してあるonTouchEventがまず呼ばれる。

そして、MapViewのonTouchEventの最後に実行する、super.onTouchEvent(event)により、MapViewに追加されている各Overlayへタッチイベントが伝えられていく、という流れのようだ。