Skip to content

Commit 49f5985

Browse files
committed
library: Refactor ExitUntilCollapsedScrollBehavior from androidx-main
1 parent c85f967 commit 49f5985

File tree

3 files changed

+36
-18
lines changed

3 files changed

+36
-18
lines changed

iosApp/iosApp/Info.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<key>CFBundleShortVersionString</key>
1818
<string>1.0.4</string>
1919
<key>CFBundleVersion</key>
20-
<string>513</string>
20+
<string>514</string>
2121
<key>LSRequiresIPhoneOS</key>
2222
<true/>
2323
<key>CADisableMinimumFrameDurationOnPhone</key>

miuix/src/commonMain/kotlin/top/yukonga/miuix/kmp/basic/PullToRefresh.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -468,8 +468,7 @@ private fun createPullToRefreshConnection(
468468
if (pullToRefreshState.refreshState != RefreshState.Idle) {
469469
return available
470470
}
471-
return topAppBarScrollBehavior?.nestedScrollConnection
472-
?.onPreFling(available) ?: Velocity.Zero
471+
return Velocity.Zero
473472
}
474473

475474
override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity {

miuix/src/commonMain/kotlin/top/yukonga/miuix/kmp/basic/TopAppBar.kt

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ fun SmallTopAppBar(
228228
fun MiuixScrollBehavior(
229229
state: TopAppBarState = rememberTopAppBarState(),
230230
canScroll: () -> Boolean = { true },
231-
snapAnimationSpec: AnimationSpec<Float>? = spring(stiffness = 3000f),
231+
snapAnimationSpec: AnimationSpec<Float>? = spring(stiffness = 2500f),
232232
flingAnimationSpec: DecayAnimationSpec<Float>? = rememberSplineBasedDecay()
233233
): ScrollBehavior =
234234
remember(state, canScroll, snapAnimationSpec, flingAnimationSpec) {
@@ -424,10 +424,13 @@ private class ExitUntilCollapsedScrollBehavior(
424424
override var nestedScrollConnection =
425425
object : NestedScrollConnection {
426426
override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
427+
// Don't intercept if scrolling down.
427428
if (!canScroll() || available.y > 0) return Offset.Zero
428429
val prevHeightOffset = state.heightOffset
429-
state.heightOffset += available.y
430+
state.heightOffset = state.heightOffset + available.y
430431
return if (prevHeightOffset != state.heightOffset) {
432+
// We're in the middle of top app bar collapse or expand.
433+
// Consume only the scroll on the Y axis.
431434
available.copy(x = 0f)
432435
} else {
433436
Offset.Zero
@@ -439,25 +442,35 @@ private class ExitUntilCollapsedScrollBehavior(
439442
available: Offset,
440443
source: NestedScrollSource,
441444
): Offset {
442-
if (!canScroll() || available.y < 0) return Offset.Zero
445+
if (!canScroll()) return Offset.Zero
443446
state.contentOffset += consumed.y
444-
val oldHeightOffset = state.heightOffset
445-
state.heightOffset += available.y
446-
return Offset(0f, state.heightOffset - oldHeightOffset)
447-
}
448447

449-
override suspend fun onPreFling(available: Velocity): Velocity {
450-
if (available.y < 0 && state.heightOffset < 0f) {
451-
return settleAppBar(state, available.y, flingAnimationSpec, snapAnimationSpec)
448+
if (available.y < 0f || consumed.y < 0f) {
449+
// When scrolling up, just update the state's height offset.
450+
val oldHeightOffset = state.heightOffset
451+
state.heightOffset = state.heightOffset + consumed.y
452+
return Offset(0f, state.heightOffset - oldHeightOffset)
453+
}
454+
455+
if (available.y > 0f) {
456+
// Adjust the height offset in case the consumed delta Y is less than what was
457+
// recorded as available delta Y in the pre-scroll.
458+
val oldHeightOffset = state.heightOffset
459+
state.heightOffset = state.heightOffset + available.y
460+
return Offset(0f, state.heightOffset - oldHeightOffset)
452461
}
453-
return Velocity.Zero
462+
return Offset.Zero
454463
}
455464

456465
override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity {
457466
if (available.y > 0) {
458-
return settleAppBar(state, available.y, flingAnimationSpec, snapAnimationSpec)
467+
// Reset the total content offset to zero when scrolling all the way down. This
468+
// will eliminate some float precision inaccuracies.
469+
state.contentOffset = 0f
459470
}
460-
return Velocity.Zero
471+
val superConsumed = super.onPostFling(consumed, available)
472+
return superConsumed +
473+
settleAppBar(state, available.y, flingAnimationSpec, snapAnimationSpec)
461474
}
462475
}
463476
}
@@ -484,10 +497,16 @@ private suspend fun settleAppBar(
484497
flingAnimationSpec: DecayAnimationSpec<Float>?,
485498
snapAnimationSpec: AnimationSpec<Float>?,
486499
): Velocity {
500+
// Check if the app bar is completely collapsed/expanded. If so, no need to settle the app bar,
501+
// and just return Zero Velocity.
502+
// Note that we don't check for 0f due to float precision with the collapsedFraction
503+
// calculation.
487504
if (state.collapsedFraction < 0.01f || state.collapsedFraction == 1f) {
488505
return Velocity.Zero
489506
}
490507
var remainingVelocity = velocity
508+
// In case there is an initial velocity that was left after a previous user fling, animate to
509+
// continue the motion to expand or collapse the app bar.
491510
if (flingAnimationSpec != null && abs(velocity) > 1f) {
492511
var lastValue = 0f
493512
AnimationState(initialValue = 0f, initialVelocity = velocity).animateDecay(
@@ -503,6 +522,7 @@ private suspend fun settleAppBar(
503522
if (abs(delta - consumed) > 0.5f) this.cancelAnimation()
504523
}
505524
}
525+
// Snap if animation specs were provided.
506526
if (snapAnimationSpec != null) {
507527
if (state.heightOffset < 0 && state.heightOffset > state.heightOffsetLimit) {
508528
AnimationState(initialValue = state.heightOffset).animateTo(
@@ -515,7 +535,6 @@ private suspend fun settleAppBar(
515535
) {
516536
state.heightOffset = value
517537
}
518-
return Velocity(0f, velocity - remainingVelocity)
519538
}
520539
}
521540
return Velocity(0f, velocity - remainingVelocity)
@@ -860,4 +879,4 @@ private fun SmallTopAppBarLayout(
860879
)
861880
}
862881
}
863-
}
882+
}

0 commit comments

Comments
 (0)