Bravo
Bravo

Reputation: 1139

Smooth User Location Tracking in Mapbox Android

I'm working on an Android map app with a location button that animates the camera to the user's location and follows their movement. However, when the user is in motion (e.g., driving), there's a noticeable jump in the map's position after the animation completes. This occurs because the user's location changes while the animation is in progress. I thought of updating dynamically the target value of the pending animation, however, I'm afraid this is not possible in Mapbox.

Here's a snippet of my code:

var isAnimating = false
    
val initialOptions = CameraOptions.Builder()
    .center(currentUserPosition)
    .build()
    
val animationOptions = MapAnimationOptions.Builder()
    .duration(600)
    .animatorListener(animationListener) // listener updates isAnimating flag
    .build()
    
map.easeTo(initialOptions, animationOptions)

location.addOnIndicatorPositionChangedListener {
    if (!isAnimating) {
        val options = CameraOptions.Builder()
            .center(it)
            .build()

        map.setCamera(options)
        gestures.focalPoint = map.pixelForCoordinate(it)
    }
}

I'm seeking advice on how to make the camera smoothly follow the user's movement without the noticeable jump after the animation finishes. Any insights or ideas would be greatly appreciated.

Upvotes: 2

Views: 919

Answers (2)

Jaspalsinh Gohil
Jaspalsinh Gohil

Reputation: 714

to avoid the jump after the animation, you can update the camera's position in real-time based on the user's location updates.

 var isAnimating = false
var currentCameraOptions: CameraOptions? = null // save the current camera options

// Initialize the camera position with your initial options
val initialCameraOptions = CameraOptions.Builder()
    .target(currentUserPosition)
    .zoom(INITIAL_ZOOM_LEVEL) // Set initial zoom level
    .build()

val initialOptions = CameraOptions.Builder()
    .camera(initialCameraOptions)
    .build()

val animationOptions = MapAnimationOptions.Builder()
    .duration(500)
    .animatorListener(animationListener)
    .build()

map.easeTo(initialOptions, animationOptions)

location.addOnIndicatorPositionChangedListener { userLocation ->
    if (!isAnimating) {
        // Update the target LatLng of the currentCameraOptions
        currentCameraOptions = CameraOptions.Builder(currentCameraOptions)
            .target(userLocation)
            .build()

        val options = CameraOptions.Builder()
            .camera(currentCameraOptions)
            .build()

        map.setCamera(options)
        gestures.focalPoint = map.pixelForCoordinate(userLocation)
    }
}

Upvotes: 0

Dinh Lam
Dinh Lam

Reputation: 765

I think this issue occurred because you use addOnIndicatorPositionChangedListener (it will be trigger location change without any conditions), so maybe that affect to animation if animation not completed.

You can use LocationProvider and make the frequency updates by your logic, ex delay 200ms for each update.

An example to use LocationProvider can found at: https://github.com/mapbox/mapbox-maps-android/blob/main/app/src/main/java/com/mapbox/maps/testapp/examples/LocationComponentAnimationActivity.kt

Hope this can be help you.

Upvotes: 0

Related Questions