GoogleMap+AndroidStudioでマーカーをgifアニメっぽくする

スポンサーリンク
スポンサーリンク

すごいぞ、できたぞ。若干興奮して目が冴えている。

スポンサーリンク

マーカーをアニメにしたい

public class MapsActivity extends FragmentActivity implements
        OnMapReadyCallback, GoogleMap.OnMapLoadedCallback {

    Marker marker;
    Handler handler = new Handler();
    BitmapDescriptor iconSanta;
    BitmapDescriptor iconSanta01;
    BitmapDescriptor iconSanta02;
    BitmapDescriptor iconSanta03;
    BitmapDescriptor iconSanta04;
    BitmapDescriptor iconSanta05;
    BitmapDescriptor iconSanta06;
    BitmapDescriptor iconSanta07;
    BitmapDescriptor iconSanta08;
    BitmapDescriptor iconSanta09;
    BitmapDescriptor iconSanta10;
    Runnable runnable = new Runnable() {
        @Override
        public void run() {

            switch (marker.getTag().toString()) {
                case ("i"):
                    marker.setIcon(iconSanta01);
                    marker.setTag("1");
                    break;

                case ("1"):
                    marker.setIcon(iconSanta02);
                    marker.setTag("2");
                    break;

                case ("2"):
                    marker.setIcon(iconSanta03);
                    marker.setTag("3");
                    break;

                case ("3"):
                    marker.setIcon(iconSanta04);
                    marker.setTag("4");
                    break;

                case ("4"):
                    marker.setIcon(iconSanta05);
                    marker.setTag("5");
                    break;

                case ("5"):
                    marker.setIcon(iconSanta06);
                    marker.setTag("6");
                    break;

                case ("6"):
                    marker.setIcon(iconSanta07);
                    marker.setTag("7");
                    break;

                case ("7"):
                    marker.setIcon(iconSanta08);
                    marker.setTag("8");
                    break;

                case ("8"):
                    marker.setIcon(iconSanta09);
                    marker.setTag("9");
                    break;

                case ("9"):
                    marker.setIcon(iconSanta10);
                    marker.setTag("10");
                    break;

                case ("10"):
                    marker.setIcon(iconSanta01);
                    marker.setTag("1");
                    break;
            }
            handler.postDelayed(runnable, 200);

        }
    };
    private GoogleMap mMap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);
        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

        iconSanta = BitmapDescriptorFactory.fromResource(R.drawable.christmas_santa_sori_i);
        iconSanta01 = BitmapDescriptorFactory.fromResource(R.drawable.christmas_santa_sori_01);
        iconSanta02 = BitmapDescriptorFactory.fromResource(R.drawable.christmas_santa_sori_02);
        iconSanta03 = BitmapDescriptorFactory.fromResource(R.drawable.christmas_santa_sori_03);
        iconSanta04 = BitmapDescriptorFactory.fromResource(R.drawable.christmas_santa_sori_04);
        iconSanta05 = BitmapDescriptorFactory.fromResource(R.drawable.christmas_santa_sori_05);
        iconSanta06 = BitmapDescriptorFactory.fromResource(R.drawable.christmas_santa_sori_06);
        iconSanta07 = BitmapDescriptorFactory.fromResource(R.drawable.christmas_santa_sori_07);
        iconSanta08 = BitmapDescriptorFactory.fromResource(R.drawable.christmas_santa_sori_08);
        iconSanta09 = BitmapDescriptorFactory.fromResource(R.drawable.christmas_santa_sori_09);
        iconSanta10 = BitmapDescriptorFactory.fromResource(R.drawable.christmas_santa_sori_10);

    }


    /**
     * Manipulates the map once available.
     * This callback is triggered when the map is ready to be used.
     * This is where we can add markers or lines, add listeners or move the camera. In this case,
     * we just add a marker near Sydney, Australia.
     * If Google Play services is not installed on the device, the user will be prompted to install
     * it inside the SupportMapFragment. This method will only be triggered once the user has
     * installed Google Play services and returned to the app.
     */
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        LatLng fuji = new LatLng(35.362859, 138.730883);

        BitmapDescriptor iconSanta = BitmapDescriptorFactory.fromResource(R.drawable.christmas_santa_sori_i);
        MarkerOptions option = new MarkerOptions();

        option.icon(iconSanta).position(fuji);
        marker = mMap.addMarker(option);
        mMap.moveCamera(CameraUpdateFactory.newLatLng(fuji));

        mMap.setOnMapLoadedCallback(this);

    }

    @Override
    public void onMapLoaded() {

        marker.setIcon(iconSanta);
        marker.setTag("i");
        handler.post(runnable);
    }

    protected void onDestroy() {
        super.onDestroy();

        handler.removeCallbacks(runnable);
    }

}

マーカーを画像にしたのはいいけど、動きが無いのでなんか味気なかった。動かし方を調べていたんだけど、全然見つからなかった。そんな折、StackOverflowに同じように悩んでる人を見つけ、そのポストの内容を参考にやってみた。コードは自分でも汚ねぇコードだなと思うが、できた喜びがすごい。

画像を用意する

コマ撮り画像を作成する

コマ撮りアニメの要領で、一枚ずつ画像を用意する。大変めんどくさい。

画像をdrawableにぶっこむ

ふつーにエクスプローラーでコピーしてフォルダ右クリックのペースト。なんかのダイアログが出るのでv24って付いてるやつを選んだ。

画像を扱う準備をする

BitmapDescriptor iconSanta;
BitmapDescriptor iconSanta01;
BitmapDescriptor iconSanta02;
BitmapDescriptor iconSanta03;
…

枚数分BitmapDescriptor型の変数を宣言してonCreate内で

iconSanta01 = BitmapDescriptorFactory.fromResource(R.drawable.christmas_santa_sori_01);
iconSanta02 = BitmapDescriptorFactory.fromResource(R.drawable.christmas_santa_sori_02);
iconSanta03 = BitmapDescriptorFactory.fromResource(R.drawable.christmas_santa_sori_03);
…

リソースから読み込む。10枚分書いてると心が折れそうになるけど頑張る。

マーカーの画像を変える

Marker型の変数を宣言&代入

Marker marker;
marker = mMap.addMarker(option);

GoogleMap.addMarkerの戻り値がMarkerということで、addしたマーカーを扱えるように変数に代入しとく。StackOverflowの人は、MarkerOptionsとaddMarkerを利用しようとして、できなかったから質問したみたい。あなたのおかげです、ありがとう!

OnMapLoadedCallbackを使う

public class MapsActivity extends FragmentActivity implements
        OnMapReadyCallback, GoogleMap.OnMapLoadedCallback {
mMap.setOnMapLoadedCallback(this);
@Override
public void onMapLoaded() {

    marker.setIcon(iconSanta);
    marker.setTag("i");
    handler.post(runnable);
}

onMapReady内でhandler使うと、いつまで経っても準備が終わらないとかになったりするかな(※試してない)と思ったので、onStart()的なものがないかと探したら、OnMapLoadedCallbackなるものを見つけた。Mapの準備が終わるとこの中の処理が呼ばれるみたい。ここら辺よくわかってない。

で、そこでsetTag()でマーカーに初期値を付けといてあげる。そしてまたあのHandlerさんの出番や!

Handler.postDelayed使う

Runnable runnable = new Runnable() {
    @Override
    public void run() {

        switch (marker.getTag().toString()) {
            case ("i"):
                marker.setIcon(iconSanta01);
                marker.setTag("1");
                break;

            case ("1"):
                marker.setIcon(iconSanta02);
                marker.setTag("2");
                break;

…

            case ("10"):
                marker.setIcon(iconSanta01);
                marker.setTag("1");
                break;
        }
        handler.postDelayed(runnable, 200);
    }
};

StopWatch作っててよかった、何となく分かるので臆さなかったぞ。Markerに付けたTagを調べて、コマ送りの順繰りにswitch文で処理を回してあげる。MarkerのsetIconで画像を変えられるので10枚分書いた、気が狂いそうになるけど頑張った。そんで最後のpostDelayedでコマ送りの間隔を設定した。小さくすれば早く動くし、大きくすればゆっくりになる。

所見

とにかくできて嬉しい!動いてるとやっぱかわいいね。ただ、このやり方はあんまり良いやり方じゃないみたい。こう、端末の計算資源を大きく使う感じになるらしい。Googleがgifアニメに対応してくれればいいのにな。いやー満足満足。引き続き地図をグリグリしてこっと。

参考

GIF type animation for marker in google map api ANDROID
I want to achieve a marker animation such as GIF animation. I got two images which should be blinking simultaneously. I found nothing which can acheive this in ...
Markers  |  Maps SDK for Android  |  Google Developers
Androidプログラマへの道 〜 Moonlight 明日香 〜
AndroidプログラミングのTip集です.やりたいことから調べられる逆引きハンドブックのようなものです.
くやしいのでAndroidStudioでストップウォッチ作る
リバーシの時間表示の時、訳わかんなくて悔しかったので、ストップウォッチ単体で作ってみる。つっても大体コピペコード。 ストップウォッチ色々 Handlerだけ 動いてるとこ ソース public class StopWa...

コメント

タイトルとURLをコピーしました