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
464 stars 131 forks source link

MapIdle won't fire if location pulsingEnabled is true #2116

Open mfazekas opened 1 year ago

mfazekas commented 1 year ago

Environment

Observed behavior and steps to reproduce

MapIdle callbacks are not fired if location is enabled

To reproduce use this code in the repo as SimpleMapActivity.

package com.mapbox.maps.testapp.examples

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.mapbox.geojson.Point
import com.mapbox.maps.CameraOptions
import com.mapbox.maps.MapView
import com.mapbox.maps.plugin.locationcomponent.location

/**
 * Example of displaying a map.
 */
class SimpleMapActivity : AppCompatActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val mapView = MapView(this)
    setContentView(mapView)
    mapView.getMapboxMap()
      .apply {
        setCamera(
          CameraOptions.Builder()
            .center(Point.fromLngLat(LONGITUDE, LATITUDE))
            .zoom(9.0)
            .build()
        )
      }
    mapView.getMapboxMap().addOnStyleLoadedListener {
      mapView.getMapboxMap().addOnMapIdleListener { event ->
        print(" [] => On MapIdle: ${event}")
      }
      if (true) {
        mapView.location.updateSettings {
          enabled = true
          pulsingEnabled = true
        }
      }
    }

  }

  companion object {
    private const val LATITUDE = 40.0
    private const val LONGITUDE = -74.5
  }
}

Expected behavior

MapIdle callbacks should be called even if location is enabled

Notes / preliminary analysis

It looks location pulsing prevents onMapIdle to be called.

Additional links and references

See #1944

kiryldz commented 1 year ago

@mfazekas thanks for the ticket. Just to clarify:

  1. If the puck with pulsing is in current viewport - that's expected behaviour as MapIdle event actually means that we have no render repaint calls and we always redraw the map if pulsing is enabled. In that case you will have to introduce your own workaround based on your requirements as described here.
  2. If the puck with pulsing is not in the current viewport (not visible on the screen) - that indeed looks like a bug in the renderer. I could not provide the timeline for this fix though but you could also try the workaround to e.g. disable pulsing if camera is moved away from the puck and enable again when the puck is in the viewport.
mfazekas commented 1 year ago

@kiryldz thanks much for the quick answer. I do see the issue when the location is not visible - not in current viewport. I'll also find out what's the use case for MapIdle as I'm working on the react-native library, and make a better alternative for that based on camera animation listeners.