mapbox / mapbox-maps-android

Interactive, thoroughly customizable maps in native Android powered by vector tiles and OpenGL.
https://www.mapbox.com/mobile-maps-sdk
Other
468 stars 131 forks source link

Lossing map state in combination with Jetpack Navigation UI / Fragment #1418

Open cleemansen opened 2 years ago

cleemansen commented 2 years ago

Environment

Observed behavior and steps to reproduce

Loosing state as I am navigating back to start destination. See demo:

  1. Starting on first tab of bottom navigation bar: Home
  2. Moving camera away from New York
  3. Navigating to second Tab (and scrolling down the list-view)
  4. Navigating back to first tab
  5. 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

Additional links and references

I disucussed this situation in past also with the android team.

cleemansen commented 2 years ago

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
    }

}