fix: 小幅度下拉时触发刷新

This commit is contained in:
HuanCheng65 2023-10-06 18:46:23 +08:00
parent 0c09d3690f
commit 03c34924d1
No known key found for this signature in database
GPG Key ID: 5EC9DD60A32C7360
3 changed files with 24 additions and 34 deletions

View File

@ -1172,22 +1172,18 @@ private val <T> SwipeableState<T>.LoadPreDownPostUpNestedScrollConnection: Neste
override suspend fun onPreFling(available: Velocity): Velocity { override suspend fun onPreFling(available: Velocity): Velocity {
val toFling = Offset(available.x, available.y).toFloat() val toFling = Offset(available.x, available.y).toFloat()
return if (toFling > 0) { return if (toFling < 0 && offset.value > minBound) {
performFling(velocity = toFling) performFling(velocity = toFling)
// since we go to the anchor with tween settling, consume all for the best UX // since we go to the anchor with tween settling, consume all for the best UX
// available available
Velocity.Zero
} else { } else {
Velocity.Zero Velocity.Zero
} }
} }
override suspend fun onPostFling( override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity {
consumed: Velocity,
available: Velocity,
): Velocity {
performFling(velocity = Offset(available.x, available.y).toFloat()) performFling(velocity = Offset(available.x, available.y).toFloat())
return Velocity.Zero return available
} }
private fun Float.toOffset(): Offset = Offset(0f, this) private fun Float.toOffset(): Offset = Offset(0f, this)

View File

@ -247,22 +247,18 @@ private val <T> SwipeableState<T>.LoadPreUpPostDownNestedScrollConnection: Neste
override suspend fun onPreFling(available: Velocity): Velocity { override suspend fun onPreFling(available: Velocity): Velocity {
val toFling = Offset(available.x, available.y).toFloat() val toFling = Offset(available.x, available.y).toFloat()
return if (toFling > 0) { return if (toFling > 0 && offset.value < maxBound) {
performFling(velocity = toFling) performFling(velocity = toFling)
// since we go to the anchor with tween settling, consume all for the best UX // since we go to the anchor with tween settling, consume all for the best UX
// available available
Velocity.Zero
} else { } else {
Velocity.Zero Velocity.Zero
} }
} }
override suspend fun onPostFling( override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity {
consumed: Velocity,
available: Velocity
): Velocity {
performFling(velocity = Offset(available.x, available.y).toFloat()) performFling(velocity = Offset(available.x, available.y).toFloat())
return Velocity.Zero return available
} }
private fun Float.toOffset(): Offset = Offset(0f, this) private fun Float.toOffset(): Offset = Offset(0f, this)

View File

@ -83,12 +83,12 @@ open class SwipeableState<T>(
val overflow: State<Float> get() = overflowState val overflow: State<Float> get() = overflowState
// Use `Float.NaN` as a placeholder while the state is uninitialised. // Use `Float.NaN` as a placeholder while the state is uninitialised.
private val offsetState = mutableStateOf(0f) private val offsetState = mutableFloatStateOf(0f)
private val overflowState = mutableStateOf(0f) private val overflowState = mutableFloatStateOf(0f)
// the source of truth for the "real"(non ui) position // the source of truth for the "real"(non ui) position
// basically position in bounds + overflow // basically position in bounds + overflow
private val absoluteOffset = mutableStateOf(0f) private val absoluteOffset = mutableFloatStateOf(0f)
// current animation target, if animating, otherwise null // current animation target, if animating, otherwise null
private val animationTarget = mutableStateOf<Float?>(null) private val animationTarget = mutableStateOf<Float?>(null)
@ -110,8 +110,8 @@ open class SwipeableState<T>(
requireNotNull(initialOffset) { requireNotNull(initialOffset) {
"The initial value must have an associated anchor." "The initial value must have an associated anchor."
} }
offsetState.value = initialOffset offsetState.floatValue = initialOffset
absoluteOffset.value = initialOffset absoluteOffset.floatValue = initialOffset
} }
} }
@ -166,29 +166,29 @@ open class SwipeableState<T>(
internal var thresholds: (Float, Float) -> Float by mutableStateOf({ _, _ -> 0f }) internal var thresholds: (Float, Float) -> Float by mutableStateOf({ _, _ -> 0f })
internal var velocityThreshold by mutableStateOf(0f) internal var velocityThreshold by mutableFloatStateOf(0f)
internal var resistance: ResistanceConfig? by mutableStateOf(null) internal var resistance: ResistanceConfig? by mutableStateOf(null)
internal val draggableState = DraggableState { internal val draggableState = DraggableState {
val newAbsolute = absoluteOffset.value + it val newAbsolute = absoluteOffset.floatValue + it
val clamped = newAbsolute.coerceIn(minBound, maxBound) val clamped = newAbsolute.coerceIn(minBound, maxBound)
val overflow = newAbsolute - clamped val overflow = newAbsolute - clamped
val resistanceDelta = resistance?.computeResistance(overflow) ?: 0f val resistanceDelta = resistance?.computeResistance(overflow) ?: 0f
offsetState.value = clamped + resistanceDelta offsetState.floatValue = clamped + resistanceDelta
overflowState.value = overflow overflowState.floatValue = overflow
absoluteOffset.value = newAbsolute absoluteOffset.floatValue = newAbsolute
} }
private suspend fun snapInternalToOffset(target: Float) { private suspend fun snapInternalToOffset(target: Float) {
draggableState.drag { draggableState.drag {
dragBy(target - absoluteOffset.value) dragBy(target - absoluteOffset.floatValue)
} }
} }
private suspend fun animateInternalToOffset(target: Float, spec: AnimationSpec<Float>) { private suspend fun animateInternalToOffset(target: Float, spec: AnimationSpec<Float>) {
draggableState.drag { draggableState.drag {
var prevValue = absoluteOffset.value var prevValue = absoluteOffset.floatValue
animationTarget.value = target animationTarget.value = target
isAnimationRunning = true isAnimationRunning = true
try { try {
@ -306,7 +306,7 @@ open class SwipeableState<T>(
} }
animateInternalToOffset(targetOffset, anim) animateInternalToOffset(targetOffset, anim)
} finally { } finally {
val endOffset = absoluteOffset.value val endOffset = absoluteOffset.floatValue
val endValue = anchors val endValue = anchors
// fighting rounding error once again, anchor should be as close as 0.5 pixels // fighting rounding error once again, anchor should be as close as 0.5 pixels
.filterKeys { anchorOffset -> abs(anchorOffset - endOffset) < 0.5f } .filterKeys { anchorOffset -> abs(anchorOffset - endOffset) < 0.5f }
@ -364,9 +364,9 @@ open class SwipeableState<T>(
* @return the amount of [delta] consumed * @return the amount of [delta] consumed
*/ */
fun performDrag(delta: Float): Float { fun performDrag(delta: Float): Float {
val potentiallyConsumed = absoluteOffset.value + delta val potentiallyConsumed = absoluteOffset.floatValue + delta
val clamped = potentiallyConsumed.coerceIn(minBound, maxBound) val clamped = potentiallyConsumed.coerceIn(minBound, maxBound)
val deltaToConsume = clamped - absoluteOffset.value val deltaToConsume = clamped - absoluteOffset.floatValue
if (abs(deltaToConsume) > 0) { if (abs(deltaToConsume) > 0) {
draggableState.dispatchRawDelta(deltaToConsume) draggableState.dispatchRawDelta(deltaToConsume)
} }
@ -410,9 +410,7 @@ class SwipeProgress<T>(
if (from != other.from) return false if (from != other.from) return false
if (to != other.to) return false if (to != other.to) return false
if (fraction != other.fraction) return false return fraction == other.fraction
return true
} }
override fun hashCode(): Int { override fun hashCode(): Int {