Skip to content

Instantly share code, notes, and snippets.

@burnoo
Created October 17, 2022 18:58
Show Gist options
  • Save burnoo/3e632df0ccdc0e38eee3987768084b6e to your computer and use it in GitHub Desktop.
Save burnoo/3e632df0ccdc0e38eee3987768084b6e to your computer and use it in GitHub Desktop.
Google Maps Compose for Wear OS

Currently Google Maps Compose does not support Wear OS officially. The main problem is a lack of support for swipe to dissmiss gesture. I came up with a workaround to add swipe to dissmiss on edges (which currently have to be black):

@Composable
fun ComposeMap() {
    val cameraPositionState = rememberCameraPositionState()
    val focusRequester = remember { FocusRequester() }

    Box(
        modifier = Modifier.edgeSwipeToDismiss(
            rememberSwipeToDismissBoxState(),
            edgeWidth = 15.dp
        ),
        contentAlignment = Alignment.Center,
    ) {
        GoogleMap(
            modifier = Modifier
                .fillMaxSize()
                .padding(horizontal = 15.dp)
                .focusRequester(focusRequester)
                .focusable(),
            cameraPositionState = cameraPositionState,
            properties = MapProperties(isMyLocationEnabled = true),
        )
    }

    FixSwipeToDismiss(focusRequester)
}

@Composable
private fun FixSwipeToDismiss(focusRequester: FocusRequester) {
    val activity = LocalContext.current as Activity
    LaunchedEffect(Unit) {
        val rootView = activity.findViewById<ViewGroup>(android.R.id.content)
        val mapView = rootView.allViews.filterIsInstance<MapView>().first()
        launch {
            while (true) {
                mapView.requestDisallowInterceptTouchEvent(true)
                delay(100)
            }
        }

        focusRequester.requestFocus()
    }
}
Screen.Recording.2022-10-17.at.20.56.21.mov

Another improvement than can be added is zooming on rotary events:

@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun RotaryZoomMap() {
    val cameraPositionState = rememberCameraPositionState()
    val coroutineScope = rememberCoroutineScope()
    
    GoogleMap(
        modifier = Modifier.onPreRotaryScrollEvent {
            coroutineScope.launch {
                val zoomDelta = if (it.verticalScrollPixels >= 0) 1 else -1
                updateZoom(cameraPositionState, zoomDelta)
            }
            true
        },
        cameraPositionState = cameraPositionState,
    )
}

private suspend fun updateZoom(
    cameraPositionState: CameraPositionState,
    zoomDelta: Int,
) {
    val newCameraPosition = CameraPosition.fromLatLngZoom(
        cameraPositionState.position.target,
        cameraPositionState.position.zoom + zoomDelta
    )
    cameraPositionState.animate(
        CameraUpdateFactory.newCameraPosition(newCameraPosition)
    )
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment