Here is an approach using the save/restore mechanism of Fragment/Activity written in Kotlin
First create a data class that will hold the map state and make it implement Parcelable
data class MapState(
val mapType: Int,
val zoomLevel: Float,
val cameraLat: Double,
val cameraLng: Double
) : Parcelable {
constructor(parcel: Parcel) : this(
parcel.readInt(),
parcel.readFloat(),
parcel.readDouble(),
parcel.readDouble()
)
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeInt(mapType)
parcel.writeFloat(zoomLevel)
parcel.writeDouble(cameraLat)
parcel.writeDouble(cameraLng)
}
override fun describeContents(): Int {
return 0
}
companion object CREATOR : Parcelable.Creator<MapState> {
override fun createFromParcel(parcel: Parcel): MapState {
return MapState(parcel)
}
override fun newArray(size: Int): Array<MapState?> {
return arrayOfNulls(size)
}
}
}
Then in your Activity/Fragment define
private var mapState: MapState? = null
In onCreate() or in this case onViewCreated() because it's fragment, check if saved instance state is available and if so get the parcelable from it
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
mapState = if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
savedInstanceState?.getParcelable(SAVED_STATE_MAP_STATE, MapState::class.java)
} else {
@Suppress("DEPRECATION")
savedInstanceState?.getParcelable(SAVED_STATE_MAP_STATE)
}
}
in your onMapReady() method check if mapState is available, if it is restore the map state
mapState?.let {
googleMap.moveCamera(
CameraUpdateFactory.newLatLngZoom(
LatLng(it.cameraLat, it.cameraLng), it.zoomLevel
)
)
googleMap.mapType = it.mapType
} ?: run {
setupUiWithLocationPermission()
googleMap.mapType = mapType
}
Override onSaveInstanceState() method of the activity/fragment to save the map state
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
val cameraPosition = googleMap.cameraPosition
val mapState = MapState(
mapType,
cameraPosition.zoom,
cameraPosition.target.latitude,
cameraPosition.target.longitude
)
outState.putParcelable(SAVED_STATE_MAP_STATE, mapState)
}
Hope it helps :)
CameraPosition
as a parcelable object duringonSaveInstanceState()
would seem to work for a change in orientation, when it's called, but it isn't called when the user exits by touching the back button. There I'm gettingonPause()
,onStop()
,onDestroy()
- none of which give me access to the instance state Bundle. I'm just learning about state management so forgive me if I've got this wrong. – Vivyan