From 6e479633181a88e39c67a0bcc8e9a07d87d8475f Mon Sep 17 00:00:00 2001 From: Chris Arriola Date: Wed, 30 Mar 2022 11:33:46 -0700 Subject: [PATCH 1/4] feat: Support specifying animation duration for camera changes. Change-Id: I18e60574610a5c248627af75369498c9e3e16889 --- .../android/compose/CameraPositionState.kt | 20 ++++++++++++++----- 1 file changed, 15 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..b778d91e 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 @@ -173,9 +173,13 @@ 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 durationMillis the duration of the animation in milliseconds. The default animation + * duration is used if a negative value is provided. */ @UiThread - suspend fun animate(update: CameraUpdate) { + suspend fun animate(update: CameraUpdate, durationMillis: Int = -1) { val myJob = currentCoroutineContext()[Job] try { suspendCancellableCoroutine { continuation -> @@ -195,7 +199,7 @@ class CameraPositionState( "internal error; no GoogleMap available to animate position" ) } - performAnimateCameraLocked(newMap, update, continuation) + performAnimateCameraLocked(newMap, update, durationMillis, continuation) } override fun onCancelLocked() { @@ -216,7 +220,7 @@ class CameraPositionState( } } } else { - performAnimateCameraLocked(map, update, continuation) + performAnimateCameraLocked(map, update, durationMillis, continuation) } } } @@ -235,9 +239,10 @@ class CameraPositionState( private fun performAnimateCameraLocked( map: GoogleMap, update: CameraUpdate, + durationMillis: Int, continuation: CancellableContinuation ) { - map.animateCamera(update, object : GoogleMap.CancelableCallback { + val cancelableCallback = object : GoogleMap.CancelableCallback { override fun onCancel() { continuation.resumeWithException(CancellationException("Animation cancelled")) } @@ -245,7 +250,12 @@ class CameraPositionState( override fun onFinish() { continuation.resume(Unit) } - }) + } + if (durationMillis < 0) { + map.animateCamera(update, cancelableCallback) + } else { + map.animateCamera(update, durationMillis, cancelableCallback) + } doOnMapChangedLocked { check(it == null) { "New GoogleMap unexpectedly set while an animation was still running" From 09c990e8b3aaa4f510f236e06aca36770647ca80 Mon Sep 17 00:00:00 2001 From: Chris Arriola Date: Wed, 30 Mar 2022 14:17:07 -0700 Subject: [PATCH 2/4] Use null to indicate default animation duration. Change-Id: I13fcb192b0e43d40380d07ed2933cd2c29b7d14a --- .../maps/android/compose/CameraPositionState.kt | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 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 b778d91e..3ac86197 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 @@ -175,11 +175,12 @@ class CameraPositionState( * 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 durationMillis the duration of the animation in milliseconds. The default animation - * duration is used if a negative value is provided. + * @param durationMs The duration of the animation in milliseconds. If null 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, durationMillis: Int = -1) { + suspend fun animate(update: CameraUpdate, durationMs: Int? = null) { val myJob = currentCoroutineContext()[Job] try { suspendCancellableCoroutine { continuation -> @@ -199,7 +200,7 @@ class CameraPositionState( "internal error; no GoogleMap available to animate position" ) } - performAnimateCameraLocked(newMap, update, durationMillis, continuation) + performAnimateCameraLocked(newMap, update, durationMs, continuation) } override fun onCancelLocked() { @@ -220,7 +221,7 @@ class CameraPositionState( } } } else { - performAnimateCameraLocked(map, update, durationMillis, continuation) + performAnimateCameraLocked(map, update, durationMs, continuation) } } } @@ -239,7 +240,7 @@ class CameraPositionState( private fun performAnimateCameraLocked( map: GoogleMap, update: CameraUpdate, - durationMillis: Int, + durationMs: Int?, continuation: CancellableContinuation ) { val cancelableCallback = object : GoogleMap.CancelableCallback { @@ -251,10 +252,10 @@ class CameraPositionState( continuation.resume(Unit) } } - if (durationMillis < 0) { + if (durationMs == null) { map.animateCamera(update, cancelableCallback) } else { - map.animateCamera(update, durationMillis, cancelableCallback) + map.animateCamera(update, durationMs, cancelableCallback) } doOnMapChangedLocked { check(it == null) { From 3f8c1d65de69ff8fbea8c6c76e8520d6850e5e9a Mon Sep 17 00:00:00 2001 From: Chris Arriola Date: Thu, 31 Mar 2022 09:12:17 -0700 Subject: [PATCH 3/4] Use Int.MAX_VALUE for default animation. Change-Id: Ib77e018ad175e591419191a736d38c1b01bf3c45 --- .../google/maps/android/compose/CameraPositionState.kt | 9 +++++---- 1 file changed, 5 insertions(+), 4 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 3ac86197..18041719 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 @@ -175,12 +176,12 @@ class CameraPositionState( * 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 null is provided, the - * default animation duration will be used. Otherwise, the value provided must be strictly - * positive, otherwise an [IllegalArgumentException] will be thrown. + * @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, durationMs: Int? = null) { + suspend fun animate(update: CameraUpdate, durationMs: Int = MAX_VALUE) { val myJob = currentCoroutineContext()[Job] try { suspendCancellableCoroutine { continuation -> From 3f85be95c372670ea3a614c8681e9b639cf272e4 Mon Sep 17 00:00:00 2001 From: Chris Arriola Date: Thu, 31 Mar 2022 09:21:24 -0700 Subject: [PATCH 4/4] Check for MAX_VALUE for default animation. Change-Id: I65c007e74dc4d5f2d9b3469d2d4edf4c542fad72 --- .../com/google/maps/android/compose/CameraPositionState.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 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 18041719..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 @@ -241,7 +241,7 @@ class CameraPositionState( private fun performAnimateCameraLocked( map: GoogleMap, update: CameraUpdate, - durationMs: Int?, + durationMs: Int, continuation: CancellableContinuation ) { val cancelableCallback = object : GoogleMap.CancelableCallback { @@ -253,7 +253,7 @@ class CameraPositionState( continuation.resume(Unit) } } - if (durationMs == null) { + if (durationMs == MAX_VALUE) { map.animateCamera(update, cancelableCallback) } else { map.animateCamera(update, durationMs, cancelableCallback)