From aa02773b5c0c09b024615a08a29e7da588e2a689 Mon Sep 17 00:00:00 2001 From: Chris Arriola Date: Thu, 31 Mar 2022 10:07:05 -0700 Subject: [PATCH] feat: Support specifying animation duration for camera changes. (#83) * feat: Support specifying animation duration for camera changes. Change-Id: I18e60574610a5c248627af75369498c9e3e16889 * Use null to indicate default animation duration. Change-Id: I13fcb192b0e43d40380d07ed2933cd2c29b7d14a * Use Int.MAX_VALUE for default animation. Change-Id: Ib77e018ad175e591419191a736d38c1b01bf3c45 * Check for MAX_VALUE for default animation. Change-Id: I65c007e74dc4d5f2d9b3469d2d4edf4c542fad72 --- .../android/compose/CameraPositionState.kt | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/maps-compose/src/main/java/com/google/maps/android/compose/CameraPositionState.kt b/maps-compose/src/main/java/com/google/maps/android/compose/CameraPositionState.kt index cd752c98..cf1076f7 100644 --- a/maps-compose/src/main/java/com/google/maps/android/compose/CameraPositionState.kt +++ b/maps-compose/src/main/java/com/google/maps/android/compose/CameraPositionState.kt @@ -33,6 +33,7 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.cancel import kotlinx.coroutines.currentCoroutineContext import kotlinx.coroutines.suspendCancellableCoroutine +import java.lang.Integer.MAX_VALUE import kotlin.coroutines.resume import kotlin.coroutines.resumeWithException @@ -173,9 +174,14 @@ class CameraPositionState( * suspend until a map is bound and animation will begin. * * This method should only be called from a dispatcher bound to the map's UI thread. + * + * @param update the change that should be applied to the camera + * @param durationMs The duration of the animation in milliseconds. If [Int.MAX_VALUE] is + * provided, the default animation duration will be used. Otherwise, the value provided must be + * strictly positive, otherwise an [IllegalArgumentException] will be thrown. */ @UiThread - suspend fun animate(update: CameraUpdate) { + suspend fun animate(update: CameraUpdate, durationMs: Int = MAX_VALUE) { val myJob = currentCoroutineContext()[Job] try { suspendCancellableCoroutine { continuation -> @@ -195,7 +201,7 @@ class CameraPositionState( "internal error; no GoogleMap available to animate position" ) } - performAnimateCameraLocked(newMap, update, continuation) + performAnimateCameraLocked(newMap, update, durationMs, continuation) } override fun onCancelLocked() { @@ -216,7 +222,7 @@ class CameraPositionState( } } } else { - performAnimateCameraLocked(map, update, continuation) + performAnimateCameraLocked(map, update, durationMs, continuation) } } } @@ -235,9 +241,10 @@ class CameraPositionState( private fun performAnimateCameraLocked( map: GoogleMap, update: CameraUpdate, + durationMs: Int, continuation: CancellableContinuation ) { - map.animateCamera(update, object : GoogleMap.CancelableCallback { + val cancelableCallback = object : GoogleMap.CancelableCallback { override fun onCancel() { continuation.resumeWithException(CancellationException("Animation cancelled")) } @@ -245,7 +252,12 @@ class CameraPositionState( override fun onFinish() { continuation.resume(Unit) } - }) + } + if (durationMs == MAX_VALUE) { + map.animateCamera(update, cancelableCallback) + } else { + map.animateCamera(update, durationMs, cancelableCallback) + } doOnMapChangedLocked { check(it == null) { "New GoogleMap unexpectedly set while an animation was still running"