From ca373fe65e0d4ded6b8f26c0ee70af62cb701525 Mon Sep 17 00:00:00 2001 From: RareScrap Date: Sun, 7 Nov 2021 22:59:26 +0300 Subject: [PATCH] offset collapsing animation implementation --- .../me/onebone/toolbar/CollapsingToolbar.kt | 43 +++++++++++++++++++ .../java/me/onebone/toolbar/ScrollStrategy.kt | 13 ++++++ .../java/me/onebone/toolbar/SnapStrategy.kt | 12 +----- 3 files changed, 57 insertions(+), 11 deletions(-) diff --git a/lib/src/main/java/me/onebone/toolbar/CollapsingToolbar.kt b/lib/src/main/java/me/onebone/toolbar/CollapsingToolbar.kt index 1914930..d3f9a07 100644 --- a/lib/src/main/java/me/onebone/toolbar/CollapsingToolbar.kt +++ b/lib/src/main/java/me/onebone/toolbar/CollapsingToolbar.kt @@ -31,6 +31,7 @@ import androidx.compose.foundation.gestures.FlingBehavior import androidx.compose.foundation.gestures.ScrollScope import androidx.compose.foundation.gestures.ScrollableState import androidx.compose.runtime.Composable +import androidx.compose.runtime.MutableState import androidx.compose.runtime.Stable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -136,6 +137,7 @@ class CollapsingToolbarState( ) fun feedScroll(value: Float): Float = dispatchRawDelta(value) + // TODO: A strange jump in snap speed is often observed @ExperimentalToolbarApi suspend fun expand(duration: Int = CollapsingToolbarDefaults.EXPAND_DURATION) { val anim = AnimationState(height.toFloat()) @@ -149,6 +151,7 @@ class CollapsingToolbarState( } } + // TODO: A strange jump in snap speed is often observed @ExperimentalToolbarApi suspend fun collapse(duration: Int = CollapsingToolbarDefaults.COLLAPSE_DURATION) { val anim = AnimationState(height.toFloat()) @@ -162,6 +165,46 @@ class CollapsingToolbarState( } } + @ExperimentalToolbarApi + suspend fun expandOffset(snapStrategy: SnapStrategy, offsetY: MutableState) { + val anim = AnimationState(offsetY.value.toFloat()) + + anim.animateTo(0f, tween(snapStrategy.expandDuration)) { + offsetY.value = value.toInt() + } + } + + @ExperimentalToolbarApi + suspend fun collapseOffset(snapStrategy: SnapStrategy, offsetY: MutableState) { + val anim = AnimationState(offsetY.value.toFloat()) + + anim.animateTo(-minHeight.toFloat(), tween(snapStrategy.collapseDuration)) { + offsetY.value = value.toInt() + } + } + + // TODO: Is there a better solution rather OptIn ExperimentalToolbarApi? + @OptIn(ExperimentalToolbarApi::class) + internal suspend fun processSnap(strategy: SnapStrategy) { + if (progress > strategy.edge) { + expand(strategy.expandDuration) + } else { + collapse(strategy.collapseDuration) + } + } + + // TODO: Is there a better solution rather OptIn ExperimentalToolbarApi? + @OptIn(ExperimentalToolbarApi::class) + internal suspend fun processOffsetSnap(snapStrategy: SnapStrategy, offsetY: MutableState) { + val offsetProgress = + 1f - ((offsetY.value / (minHeight / 100f)) / 100f).absoluteValue + if (offsetProgress > snapStrategy.edge) { + expandOffset(snapStrategy, offsetY) + } else { + collapseOffset(snapStrategy, offsetY) + } + } + /** * @return Remaining velocity after fling */ diff --git a/lib/src/main/java/me/onebone/toolbar/ScrollStrategy.kt b/lib/src/main/java/me/onebone/toolbar/ScrollStrategy.kt index 7df3705..4b1e886 100644 --- a/lib/src/main/java/me/onebone/toolbar/ScrollStrategy.kt +++ b/lib/src/main/java/me/onebone/toolbar/ScrollStrategy.kt @@ -192,6 +192,19 @@ internal class EnterAlwaysCollapsedNestedScrollConnection( dy } + // TODO: Cancel expand/collapse animation inside onPreScroll + snapStrategy?.let { + val isToolbarChangingOffset = offsetY.value != 0//toolbarState.progress == 0f + if (isToolbarChangingOffset) { + // When the toolbar is hiding, it does it through changing the offset and does not + // change its height, so we must process not the snap of the toolbar, but the + // snap of its offset. + toolbarState.processOffsetSnap(it, offsetY) + } else { + toolbarState.processSnap(it) + } + } + return available.copy(y = available.y - left) } } diff --git a/lib/src/main/java/me/onebone/toolbar/SnapStrategy.kt b/lib/src/main/java/me/onebone/toolbar/SnapStrategy.kt index 98aecd5..8f930e2 100644 --- a/lib/src/main/java/me/onebone/toolbar/SnapStrategy.kt +++ b/lib/src/main/java/me/onebone/toolbar/SnapStrategy.kt @@ -8,14 +8,4 @@ class SnapStrategy( @FloatRange(from = 0.0, to = 1.0) val edge: Float = CollapsingToolbarDefaults.EDGE, val expandDuration: Int = CollapsingToolbarDefaults.EXPAND_DURATION, val collapseDuration: Int = CollapsingToolbarDefaults.COLLAPSE_DURATION -) - -// TODO: Is there a better solution rather OptIn ExperimentalToolbarApi? -@OptIn(ExperimentalToolbarApi::class) -internal suspend fun CollapsingToolbarState.processSnap(strategy: SnapStrategy) { - if (progress > strategy.edge) { - expand(strategy.expandDuration) - } else { - collapse(strategy.collapseDuration) - } -} \ No newline at end of file +) \ No newline at end of file