mapbox-maps-android
mapbox-maps-android copied to clipboard
Lossing map state in combination with Jetpack Navigation UI / Fragment
Environment
- Android OS version: API 32
- Devices affected: Android Emulator
- Maps SDK Version: 10.5.0
Observed behavior and steps to reproduce
Loosing state as I am navigating back to start destination. See demo:
- Starting on first tab of bottom navigation bar: Home
- Moving camera away from New York
- Navigating to second Tab (and scrolling down the list-view)
- Navigating back to first tab
- Camera moved to initial camera position New York. My view-state was not retained.
https://user-images.githubusercontent.com/868171/172797888-40ff0756-6f0e-4366-8e57-6d0c091bb6bb.mov
Expected behavior
The map state retains
Notes / preliminary analysis
- as you can see in the final step (navigating again to second tab) the list-view retains its state
- this MRE is based on NavigationAdvandedSample
- you can apply this patch to reproduce the MRE patch_navigation-ui_mapbox.txt
Additional links and references
I disucussed this situation in past also with the android team.
As a first workaround I cache the camera-position on my own and retain it during map recreation
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.mapbox.maps.*
class MapFragment : Fragment() {
private var mapView: MapView? = null
private var retainedCamera: CameraState? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_map, container, false)
mapView = view.findViewById(R.id.mapView)
mapView?.getMapboxMap()?.loadStyleUri(Style.SATELLITE_STREETS)
// workaround for https://github.com/mapbox/mapbox-maps-android/issues/1418
if (retainedCamera != null) {
mapView
?.getMapboxMap()
?.setCamera(CameraOptions.Builder()
.zoom(retainedCamera!!.zoom)
.center(retainedCamera!!.center)
.pitch(retainedCamera!!.pitch)
.bearing(retainedCamera!!.bearing)
.padding(retainedCamera!!.padding)
.build()
)
}
return view
}
override fun onPause() {
super.onPause()
retainedCamera = mapView?.getMapboxMap()?.cameraState
}
}