Search code examples
google-mapsandroid-jetpack-composeaccessibilitygoogle-maps-markersgoogle-maps-compose

Ignore for accessibility with Google Maps compose SDK


Background

I have a hybrid search in a production app that uses google-maps-compose's GoogleMap composable. This search offers a bottom sheet that displays a list of results along with a map with pins. We would like to push visually impaired users to the bottom sheet results. To do this we need to make the GoogleMap composable unfocusable. This seems to be impossible. It absorbs focus even through other components.

Example

@Composable
private fun AccessibilityExample() {
    val markerStateSydney = remember { MarkerState(position = LatLng(-34.0, 151.0)) }
    val markerStateTokyo = remember { MarkerState(position = LatLng(35.66, 139.6)) }

    BottomSheetScaffold(
        sheetContent = {
            Spacer(
                modifier = Modifier
                    .background(
                        color = Color.Gray,
                        shape = RoundedCornerShape(topStart = 8.dp, topEnd = 8.dp),
                    )
                    .fillMaxWidth()
                    .fillMaxHeight(0.5f)
            )
        },
    ) {
        GoogleMap(
            modifier = Modifier
                .clearAndSetSemantics { invisibleToUser() }
                .focusable(enabled = false)
                .fillMaxSize()
        ) {
            Marker(
                state = markerStateSydney,
                title = "Marker in Sydney",
            )
            Marker(
                state = markerStateTokyo,
                title = "Marker in Tokyo"
            )
        }
    }
}

You can see here that the pin is focused through the bottom sheet.

The pin is focusable through the bottom sheet

What I have tried

I have tried all typical compose "ignore for accessibility" solutions to no avail. This includes:

  • Modifier.focusable(enabled = false)
  • Modifier.clearAndSetSemantics {}
  • Modifier.semantics { invisibleToUser() }

There is an issue with the google-maps-compose sdk concerning this.

What I need

I would love any Google attention on this issue or any work arounds anyone has found. This work around can be particular to the GoogleMap composable or any ideas of how I might "steal" focus from it.


Solution

  • It was impossible all along. The Google Maps Android Compose team recently released a fix for this. Check out this comment to learn more.

    Setting these two attributes results in the desired behavior.

    GoogleMap(
        // mergeDescendants will remove accessibility from the entire map and content inside.
        mergeDescendants = true,
        contentDescription = null,
        ...
    )
    

    So with my example the solution would be:

    private fun AccessibilityExample() {
        val markerStateSydney = remember { MarkerState(position = LatLng(-34.0, 151.0)) }
        val markerStateTokyo = remember { MarkerState(position = LatLng(35.66, 139.6)) }
    
        BottomSheetScaffold(
            sheetContent = {
                Spacer(
                    modifier = Modifier
                        .background(
                            color = Color.Gray,
                            shape = RoundedCornerShape(topStart = 8.dp, topEnd = 8.dp),
                        )
                        .fillMaxWidth()
                        .fillMaxHeight(0.5f)
                )
            },
        ) {
            GoogleMap(
                mergeDescendants = true,
                contentDescription = null,
                modifier = Modifier.fillMaxSize()
            ) {
                Marker(
                    state = markerStateSydney,
                    title = "Marker in Sydney",
                )
                Marker(
                    state = markerStateTokyo,
                    title = "Marker in Tokyo"
                )
            }
        }
    }