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アニメに対応してくれればいいのにな。いやー満足満足。引き続き地図をグリグリしてこっと。

参考

Attention Required! | Cloudflare
Markers  |  Maps SDK for Android  |  Google for Developers
リクエストされたページは表示できません - Seesaa Wiki(ウィキ)
くやしいのでAndroidStudioでストップウォッチ作る
リバーシの時間表示の時、訳わかんなくて悔しかったので、ストップウォッチ単体で作ってみる。つっても大体コピペコード。ストップウォッチ色々Handlerだけ動いてるとこソースpublic class StopWatch extends AppC...

コメント

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