質問: Google Maps Android API v2を使い地図アプリを作ろうと考えております。 地図の現在の位置(v2ではカメラの位置ですが)をリアルタイムに、地図のビューが1ピクセルでも移動した瞬間を繰り返し取得するにはどうしたらよいでしょうか。 最終的に作ろうとしている物の例は以下の動画のマーカーの動きです。 Google Maps Android API v2においてマーカーは静止画しか設定出来ないので、この動画の様なアニメーションを行う事は出来ません。 地図の上にビューを配置し、マーカーを自力で描画しようと思ったのですが、それには地図のビューが1pxでも更新されたタイミングに合わせて自力描画マーカーの位置を更新する必要があります。 setOnCameraChangeListenerでカメラの位置変更を取得しようと思ったのですが、イベントが呼ばれるタイミングが1秒に数回程度であり、自力描画マーカーの位置が全く追いついていきません。 そこで、Android Google Maps SDKで地図の現在位置をリアルタイムで取得する方法を教えて欲しいです。 タイトルから離れてしまいますが、Android Google Maps SDKで地図の上に自作のビューを貼り付ける方法でも結構です。タイルオーバーレイという物もありますが、やはりこれも静止画が基本ですので自由なビューを貼り付けたいです。
回答: 私も同じような問題にあたり、強引ですがMapFragmentのViewに自作のViewを重ねる方法を使いました。 重ねたViewはOnGestureListenerをimplementしたFrameLayoutです。 私が使っているのは以下のような感じです。 試行錯誤中で要らない処理が含まれている可能性がありますが、参考になればと思います。 これで地図をドラッグしたり、フリックしたりする動きには逐一ついていきますが、例えば GoogleMap#animateCamera()で移動した場合などは別の処理が必要です。 ``` public class TouchableWrapper extends FrameLayout implements GestureDetector.OnGestureListener{ protected GestureDetector gd; private Scroller scroller; private final Handler handler = new Handler(); public TouchableWrapper(Context context) { super(context); scroller = new Scroller(context); init(); } public void init(){ gd = new GestureDetector(getContext(),this); } @Override public boolean onInterceptTouchEvent(MotionEvent ev){ super.onInterceptTouchEvent(ev); gd.onTouchEvent(ev); return false; } @Override public boolean dispatchTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: //ここに移動の処理、座標の取得等 break; case MotionEvent.ACTION_MOVE: //ここに移動の処理、座標の取得等 break; case MotionEvent.ACTION_UP: //ここに移動の処理、座標の取得等 break; case MotionEvent.ACTION_CANCEL: //ここに移動の処理、座標の取得等 break; } return super.dispatchTouchEvent(ev); } @Override public boolean onDown(MotionEvent e) { return false; } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { scroller.fling( (int)e2.getX(), (int)e2.getY(), (int)velocityX, (int)velocityY, 0, getWidth(), 0, getHeight()); handler.post(new Runnable() { @Override public void run() { scroller.computeScrollOffset(); //ここに移動の処理、座標の取得等 invalidate(); if(!scroller.isFinished()){ handler.postDelayed(this, 50); } } }); return false; } @Override public void onLongPress(MotionEvent e) { } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { return false; } @Override public void onShowPress(MotionEvent e) { } @Override public boolean onSingleTapUp(MotionEvent e) { return false; } } ``` ジェスチャーについてはこちらを参考にしました。 【Android】GestuerDetectorとScrollerを組み合わせた例 |ザワプロ!