MapViewportState transitionToOverviewState is sometimes not working + black parts while rendering
Environment
- Android OS version: all
- Devices affected: all
- Maps SDK Version: 11.4.0
Observed behavior and steps to reproduce
We are showing a trip in an embedded map or a full screen map on the same screen via the MapboxMap composable in our app. The user can switch between the embedded map and the full screen map. This is implemented by increasing the height of the Box where the MapboxMap is placed in, i.e., Modifier.fillMaxHeight is used for the full screen mode and a fixed size is used for the embedded mode.
The user can only interact in the full screen mode with the map by using gestures. Since the full screen map is larger than the embedded map, we call mapViewportState.transitionToOverviewState to ensure the whole trip can be seen in both modes. When the user zooms in on the full screen map and switches back to the embedded map, sometimes this call has no effect, leading to an embedded map showing only parts of the trip.
In addition, during the height change of the map, the map is only rendered partly, i.e., some parts are black (see screenshot below). Please note, that I removed all location information for data privacy reasons. Could you also fix this?
Expected behavior
We would expect the mapViewportState.transitionToOverviewState call to work every time, i.e., switching between full screen map and embedded map should always lead to a totally visible trip.
In addition, we would expect the trip to render without black parts, ideally in the background color of the app content. If this is not possible out of the box, it would be perfect to specifiy the rendering background color in the app.
Notes / preliminary analysis
We could temporarily fix, that the mapViewportState.transitionToOverviewState method is not working every time by introducing a small delay before calling this method. However, it would be better, if we could rely on the functionality of this method.
It seems, that the rendering works in the following way:
- Embedded map is rendered
- Height changes and embedded map is moved to the top of the rendering area (height remains the same, not rendered part is black)
- Missing parts are rendered and already rendered part of the map is moved to the previous position
Could it be possible to retain the position and render the missing parts below and above the already rendered part?
Screenshots
@pengdev Any news regarding this?
Hi @lukaspetry thanks for the report, could you please provide some code snippets on how you position the map, and how do you toggle between these two modes? It would be good to reproduce it locally.
As a side note, the transitionToOverviewState relies on the cameraForCoordinates API and it is only usable when the reader thread is ready(e.g. mapSize is available), this might explain delaying a few millisecond helps in your case, we do have a async version of it introduced lately that might help to fix this specific issue.
That said, a minimum reproducing project/branch would be really helpful to debug further.
Hi @pengdev, thanks for your reply! Due to company restrictions, I can't provide you the code as it is, but I added a Compose setup below, which shows, how we position the map and how we toggle between these two modes.
Where can we find the async version of the transitionToOverviewState method? I searched for the async version in the docs, but I only found the normal version.
Here's the Compose code for reproducing the bug:
@Composable
fun MapPositionReproduction() {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
val context = LocalContext.current
// This should indicate that we can show something below the map in fullscreen
// mode but we do this not for every trip - I added this as explanation for the
// Column below. Otherwise, the Column wouldn't be necessary.
val isAdditionalInfoGiven by remember {
mutableStateOf(false)
}
// switching between embedded map and fullscreen map is controlled via this state variable
var isMapFullscreen by remember {
mutableStateOf(false)
}
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Column(
modifier = Modifier
.padding(innerPadding)
.fillMaxWidth()
.then(
if (isMapFullscreen) {
Modifier.fillMaxHeight()
} else {
Modifier.height(300.dp)
}
),
) {
Box(
modifier = Modifier.weight(1f),
contentAlignment = Alignment.BottomEnd
) {
LaunchedEffect(isMapFullscreen, isAdditionalInfoGiven) {
// that's the workaround for fixing that the mapViewportState.transitionToOverviewState
// call has sometimes no effect
delay(100)
// here we would normally call the method mapViewportState.transitionToOverviewState
Toast.makeText(
context,
"mapViewportState.transitionToOverviewState called",
Toast.LENGTH_SHORT
).show()
}
MapboxMap(
modifier = Modifier
.then(
// map size can be changed by clicking on the map but only
// in embedded mode
if (isMapFullscreen) {
Modifier
} else {
Modifier.clickable {
isMapFullscreen = !isMapFullscreen
}
}
)
)
// map size can be changed by clicking on the FloatingActionButton
FloatingActionButton(
onClick = { isMapFullscreen = !isMapFullscreen },
modifier = Modifier.padding(end = 10.dp, bottom = 10.dp)
) {
Text(
modifier = Modifier.padding(10.dp),
text = "Change Map Size"
)
}
}
if (isMapFullscreen && isAdditionalInfoGiven) {
AdditionalMapInfo(modifier = Modifier)
}
}
}
}
}
@Composable
fun MapboxMap(modifier: Modifier) {
// this Box would normally be the MapboxMap composable
Box(
modifier = modifier
.fillMaxSize()
.background(color = Color.Blue)
)
}
@Composable
fun AdditionalMapInfo(modifier: Modifier) {
Row(
modifier = modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.Center
) {
Text(
modifier = Modifier.padding(10.dp),
text = "Info 1"
)
Text(
modifier = Modifier.padding(10.dp),
text = "Info 2"
)
}
}
Where can we find the async version of the transitionToOverviewState method? I searched for the async version in the docs, but I only found the normal version.
@lukaspetry This will be fixed internally in the SDK, will post here when the fix is picked up by a release.
And thanks for the code snippets, I will take a deeper look.
@lukaspetry The fix of transitionToOverviewState is landed in https://github.com/mapbox/mapbox-maps-android/releases/tag/v11.5.0, please feel free to give it a try!
Hi @pengdev, sorry for the late response. We are currently updating our integrated mapbox sdk version to 11.7.1 and I can still reproduce both bugs easily. Could you take another look at them?