0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Jetpack Compose で構築した画面に Google Map を配置する

Last updated at Posted at 2024-08-19

はじめに

  • Maps SDK for Android の MapView を使って Jetpack Compose で構成した画面に Google Map を表示する方法です
  • 今後使うかも知れないので、ここに残しておくことにしました。どなたかのお役に立てば嬉しいです
  • ちなみに元ネタは下記の Codelab です。気になった方はトライしてみてください
  • 従来の Android View で MapView を使うやり方については、以前こちらの記事で共有させて頂きました
    • かなり前の記事ですが、基本的には今でも同じ方法が使えるようです

実装

ポイントは以下の2点になるかと思います

  • ライフサイクルと同期した MapView を生成し保持する
  • コンポーザブルで MapView を 配置する

ライフサイクルと同期した MapView を生成し保持する

  • 以前の記事 にも書きましたが、 MapViewActivityFragment のライフサイクルと同期し、イベントに応じて適切なメソッドが呼び出されなくてはなりません
    • Activity.onCreate() の中で MapView.onCreate() が呼ばれなくてはならない、といった具合
    • MapView のリファレンス にもその旨の記述 (『You must call this method from the parent Activity/Fragment's corresponding method』)があります
  • ライフサイクルとの同期は、 LifecycleEventObserverDisposableEffect を組み合わせて実現するのがよさそうです
    • DisposableEffect についてはこちらが詳しいです

サンプルコード

MapView を保持/参照するためのコンポーザブルが以下です
(ほぼ元ネタそのままなので、必要に応じて手を入れるなどして頂ければと思います)

@Composable
fun rememberMapViewWithLifecycle(): MapView {
    val context = LocalContext.current
    val mapView = remember {
        MapView(context).apply { id = R.id.map_view_id }
    }

    val lifeCycle = LocalLifecycleOwner.current.lifecycle

    DisposableEffect(key1 = lifeCycle, key2 = mapView) {
        val lifecycleObserver = LifecycleEventObserver { _, event ->
            when (event) {
                Lifecycle.Event.ON_CREATE -> mapView.onCreate(Bundle())
                Lifecycle.Event.ON_START -> mapView.onStart()
                Lifecycle.Event.ON_RESUME -> mapView.onResume()
                Lifecycle.Event.ON_PAUSE -> mapView.onPause()
                Lifecycle.Event.ON_STOP -> mapView.onStop()
                Lifecycle.Event.ON_DESTROY -> mapView.onDestroy()
                else -> throw IllegalStateException()
            }
        }

        lifeCycle.addObserver(lifecycleObserver)

        onDispose {
            lifeCycle.removeObserver(lifecycleObserver)
        }
    }

    return mapView
}

コンポーザブルで MapView を 配置する

サンプルコード

JR大阪駅にマーカーを立てて、 16.0f のズーム率でマップを表示したものです

val mapView = rememberMapViewWithLifecycle()

AndroidView(
    modifier = Modifier.fillMaxSize(),
    factory = { mapView },
) { view ->
    view.getMapAsync {
        val position = LatLng(34.702473, 135.495926)
        val zoom = 16.0f

        it.addMarker(
            MarkerOptions().position(position).title("Sample Marker")
        )

        it.moveCamera(
            CameraUpdateFactory.newCameraPosition(
                CameraPosition.Builder().apply {
                    target(position)
                    zoom(zoom)
                }.build()
            )
        )
    }
}

実行結果

追記

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?