Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS native scroll and feel #609

Merged
merged 135 commits into from
Jul 10, 2023
Merged
Show file tree
Hide file tree
Changes from 134 commits
Commits
Show all changes
135 commits
Select commit Hold shift + click to select a range
0aaabd4
developmentTeamToRunOnRealDevice
dima-avdeev-jb Apr 17, 2023
a4a2a5d
Merge branch 'jb-main' into dima.avdeev/run-demo-uikit-on-deivice
dima-avdeev-jb Jun 12, 2023
c21a4d3
print jvm arch
dima-avdeev-jb Jun 12, 2023
69b717e
iOS run configuration
dima-avdeev-jb Jun 13, 2023
bb18b67
redundant run configurations
dima-avdeev-jb Jun 13, 2023
3b04108
run configurations
dima-avdeev-jb Jun 13, 2023
a8be2fe
Revert "run configurations"
dima-avdeev-jb Jun 13, 2023
bd63456
Revert "redundant run configurations"
dima-avdeev-jb Jun 13, 2023
a6f217d
Revert "iOS run configuration"
dima-avdeev-jb Jun 13, 2023
cef682d
simplify
dima-avdeev-jb Jun 13, 2023
0d60bd2
check runOnDevice correctly
dima-avdeev-jb Jun 13, 2023
d0aeb8f
update README
dima-avdeev-jb Jun 13, 2023
1de8717
update README
dima-avdeev-jb Jun 13, 2023
dc6c772
run with Xcode
dima-avdeev-jb Jun 13, 2023
0cf59fa
run with Xcode
dima-avdeev-jb Jun 13, 2023
3cf9d3b
run with Xcode
dima-avdeev-jb Jun 13, 2023
640d2e3
doc run mpp/demo-uikit sample on iOS
dima-avdeev-jb Jun 13, 2023
c4de446
projectProperties
dima-avdeev-jb Jun 13, 2023
f505e57
projectProperties
dima-avdeev-jb Jun 13, 2023
bc09c91
fix iOS on x86-64
dima-avdeev-jb Jun 13, 2023
903de00
simplify demo-uikit
dima-avdeev-jb Jun 14, 2023
231de6e
Added check to TEAM_ID
dima-avdeev-jb Jun 14, 2023
947b295
Add geometry functions to Offset.kt
elijah-semyonov Jun 14, 2023
dc7523a
Implement DecelerationTimingParameters
elijah-semyonov Jun 14, 2023
c356416
add feature flag
dima-avdeev-jb Jun 14, 2023
88d0af8
Add RubberBand effect business logic
elijah-semyonov Jun 15, 2023
cf5116b
Fix comment
elijah-semyonov Jun 15, 2023
1f4ae57
Refactor RubberBand
elijah-semyonov Jun 15, 2023
baaf888
WIP: start experimenting
elijah-semyonov Jun 15, 2023
afca754
Revert Scroll.kt changes
elijah-semyonov Jun 15, 2023
89cd9f2
Chop OvercrollEffect actual providers into uikit and macos targets. I…
elijah-semyonov Jun 16, 2023
560334a
Implement working stub for iOS.
elijah-semyonov Jun 16, 2023
f828c29
Implement rubber band logic in IOSOverScrollEffect
elijah-semyonov Jun 19, 2023
7dcbdc1
Delete dead code, mark private members accordingly.
elijah-semyonov Jun 19, 2023
4900222
Explicitly pass environmental variables to Xcode build script.
elijah-semyonov Jun 19, 2023
29a9200
Integrate COMPOSE_DEMO_APPLE_TEAM_ID variable into xcodegen
elijah-semyonov Jun 19, 2023
e426f3b
Merge branch 'elijah.semyonov/export-java-home-to-xcodegen' into elij…
elijah-semyonov Jun 19, 2023
fe45593
Add stub for demo with spring animation
elijah-semyonov Jun 20, 2023
49dd06d
Add Underdamped spring solution
elijah-semyonov Jun 20, 2023
faf14fb
Create logic for making spring solution
elijah-semyonov Jun 20, 2023
2efb9ff
Snapshot
elijah-semyonov Jun 21, 2023
38e92a0
Remove dead code.
elijah-semyonov Jun 21, 2023
296048d
Add spec-based implementation
elijah-semyonov Jun 21, 2023
810f3aa
Add test case to check animation
elijah-semyonov Jun 21, 2023
a254951
Merge remote-tracking branch 'origin/dima.avdeev/run-demo-uikit-on-de…
elijah-semyonov Jun 21, 2023
21e4157
Snapshot
elijah-semyonov Jun 22, 2023
27d8493
Merge branch 'jb-main' into elijah.semyonov/ios-scroll-behavior
elijah-semyonov Jun 22, 2023
2c533a1
Snapshot
elijah-semyonov Jun 22, 2023
02bcfd1
Snapshot
elijah-semyonov Jun 23, 2023
9f0e6a1
Snapshot
elijah-semyonov Jun 23, 2023
9c58383
Snapshot everything except edge case working
elijah-semyonov Jun 23, 2023
1e5a1b2
Move connecting fling behavior and overscroll further down the tree
elijah-semyonov Jun 23, 2023
ff1b797
Add back button on nested selection screens in Demo App
elijah-semyonov Jun 23, 2023
da13f92
Play spring animation on zero velocity fling.
elijah-semyonov Jun 23, 2023
8d28804
Remove dead code
elijah-semyonov Jun 23, 2023
d1b9fbf
Snapshot before fling from overscroll edge case
elijah-semyonov Jun 26, 2023
f3df5d5
Resolve edge case of flinging from inside overscroll area
elijah-semyonov Jun 26, 2023
0019db5
Update documentation
elijah-semyonov Jun 26, 2023
e7846fd
Refactor boolean value to OverscrollOffsetSpace enum
elijah-semyonov Jun 26, 2023
c3a7b57
Refactor boolean value to OverscrollOffsetSpace enum
elijah-semyonov Jun 26, 2023
50731c6
Modify API to support interaction between OverscrollEffect and FlingB…
elijah-semyonov Jun 27, 2023
4c581aa
Delete dead code.
elijah-semyonov Jun 27, 2023
0b5480c
Update comment.
elijah-semyonov Jun 27, 2023
21ea9ac
Update comment.
elijah-semyonov Jun 27, 2023
3d96270
Move division by density outside of Offset
elijah-semyonov Jun 27, 2023
f8cc171
Revert "Add geometry functions to Offset.kt"
elijah-semyonov Jun 27, 2023
b0847cb
Remove redundant import
elijah-semyonov Jun 27, 2023
e903242
Remove redundant CupertinoFlingBehavior.
elijah-semyonov Jun 27, 2023
55c4f88
Remove redundant constructor arg
elijah-semyonov Jun 27, 2023
5656f02
Refine documentation
elijah-semyonov Jun 27, 2023
d5ad295
Modify android code and tests to conform to API change
elijah-semyonov Jun 27, 2023
40ccd15
Update document
elijah-semyonov Jun 27, 2023
95f26e8
Reset change
elijah-semyonov Jun 29, 2023
36f2db4
Remove gradle line.
elijah-semyonov Jun 29, 2023
fc07d2c
Revert changes
elijah-semyonov Jun 29, 2023
5d686de
Revert changes
elijah-semyonov Jun 29, 2023
f8aca64
Revert changes
elijah-semyonov Jun 29, 2023
abeaaed
Add comment
elijah-semyonov Jun 29, 2023
68d8d78
Make constant internal
elijah-semyonov Jun 29, 2023
c50176e
Revert Scrollable.kt.
elijah-semyonov Jun 29, 2023
3476d84
Bring CupertinoFlingBehavior back
elijah-semyonov Jun 29, 2023
f63e991
Revert changes.
elijah-semyonov Jun 29, 2023
ac20ac2
Revert API change.
elijah-semyonov Jun 29, 2023
ba99992
Updater converter interface
elijah-semyonov Jun 29, 2023
bcdc708
Update CupertinoOverscrollEffect
elijah-semyonov Jun 29, 2023
13c2053
Update CupertinoOverscrollEffect
elijah-semyonov Jun 29, 2023
a92b64b
Revert "Modify android code and tests to conform to API change"
elijah-semyonov Jun 29, 2023
3d3cd83
Revert changes
elijah-semyonov Jun 29, 2023
f7bc248
Remove dead code mentions
elijah-semyonov Jun 29, 2023
38d2815
Bind cupertino fling and overscroll behavior together
elijah-semyonov Jun 29, 2023
98befdf
Fix a wrong construction argument bug
elijah-semyonov Jun 29, 2023
5ae776a
Revert line
elijah-semyonov Jun 29, 2023
ecc6cd9
Remove unneeded imports
elijah-semyonov Jun 29, 2023
d2088f5
Remove rubberband/linear space logic. iOS seems to calculate everythi…
elijah-semyonov Jun 29, 2023
2822d84
Update stiffness to counteract rubbe-band space visual feedback.
elijah-semyonov Jun 29, 2023
211c52b
Fix typo.
elijah-semyonov Jun 29, 2023
9031f3b
Return it back.
elijah-semyonov Jun 29, 2023
69a98be
Refactor density injection logic.
elijah-semyonov Jun 29, 2023
4326cd7
Fix edge case.
elijah-semyonov Jun 29, 2023
7ad4f86
Change var to val
elijah-semyonov Jun 29, 2023
a2a9989
Remove new line
elijah-semyonov Jun 29, 2023
2e702ac
Fix formatting
elijah-semyonov Jun 29, 2023
c00d5db
Fix typo
elijah-semyonov Jun 30, 2023
84b5062
Adjust fling from overscroll logic
elijah-semyonov Jun 30, 2023
0b89b95
Implement Cupertino behavior using old API
elijah-semyonov Jun 30, 2023
6257a48
Remove println
elijah-semyonov Jun 30, 2023
9d30627
Fix RTL and add demo
elijah-semyonov Jun 30, 2023
de97c8e
Make added API internal
elijah-semyonov Jun 30, 2023
4d38daa
Add optOut API
elijah-semyonov Jun 30, 2023
855b90d
Update comment
elijah-semyonov Jul 4, 2023
e92775b
Remove ScrollValueConverter altogether.
elijah-semyonov Jul 4, 2023
39b8000
Update documentation
elijah-semyonov Jul 4, 2023
179e39b
Move CupertinoScrollDecayAnimationSpec to uikit source set
elijah-semyonov Jul 4, 2023
536913c
Merge branch 'jb-main' into elijah.semyonov/ios-scroll-behavior
elijah-semyonov Jul 4, 2023
8652190
Move CupertinoOverscrollEffect to cupertino module
elijah-semyonov Jul 4, 2023
0df8a26
Change visibility modifer
elijah-semyonov Jul 4, 2023
ae19a60
Change visibility modifier
elijah-semyonov Jul 4, 2023
7ab75f2
Merge remote-tracking branch 'origin/elijah.semyonov/ios-scroll-behav…
elijah-semyonov Jul 4, 2023
5dce6c1
Move CupertinoScrollDecayAnimationSpec to cupertino module
elijah-semyonov Jul 4, 2023
838dcd5
Revert visibility modifier change.
elijah-semyonov Jul 4, 2023
ae1b429
Fix formatting
elijah-semyonov Jul 4, 2023
b974bc3
Remove dead code.
elijah-semyonov Jul 4, 2023
1962694
Use specific type instead of a Pair
elijah-semyonov Jul 4, 2023
336ab1e
Add explicit arguments' names
elijah-semyonov Jul 4, 2023
3f7afb0
Update formatting
elijah-semyonov Jul 4, 2023
dd8af4c
Replace boolean with enum
elijah-semyonov Jul 4, 2023
dca1cfb
Move Velocity<->Offset conversions to file scope.
elijah-semyonov Jul 4, 2023
8fedbc0
Replace default decelerationRate with iOS constant instead of literal
elijah-semyonov Jul 4, 2023
a6f835b
Merge branch 'jb-main' into elijah.semyonov/ios-scroll-behavior
elijah-semyonov Jul 10, 2023
08b67eb
Remove extra line
elijah-semyonov Jul 10, 2023
8859691
Move opt-out rubber banding to ScrollConfig
elijah-semyonov Jul 10, 2023
2ac2f53
Move opt-out rubber banding to ScrollConfig
elijah-semyonov Jul 10, 2023
baac6e4
Refactor last change a bit
elijah-semyonov Jul 10, 2023
99dd70a
Rename UIKitScroll config
elijah-semyonov Jul 10, 2023
c5ab1e1
Fix experimental annotation to correct one
elijah-semyonov Jul 10, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package androidx.compose.animation.core

import androidx.compose.animation.core.internal.JvmDefaultWithCompatibility
import kotlin.math.roundToLong

/**
* This interface provides a convenient way to query from an [VectorizedAnimationSpec] or
Expand Down Expand Up @@ -90,6 +91,13 @@ internal val Animation<*, *>.durationMillis: Long
get() = durationNanos / MillisToNanos

internal const val MillisToNanos: Long = 1_000_000L
internal const val SecondsToNanos: Long = 1_000_000_000L

internal fun convertSecondsToNanos(seconds: Float): Long =
(seconds.toDouble() * SecondsToNanos).roundToLong()

internal fun convertNanosToSeconds(nanos: Long): Double =
nanos.toDouble() / SecondsToNanos

/**
* Returns the velocity of the animation at the given play time.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package androidx.compose.animation.core.cupertino

import androidx.compose.animation.core.FloatDecayAnimationSpec
import androidx.compose.animation.core.convertNanosToSeconds
import androidx.compose.animation.core.convertSecondsToNanos
import kotlin.math.abs
import kotlin.math.ln
import kotlin.math.pow
import platform.UIKit.UIScrollViewDecelerationRateNormal

/**
* A class that represents the animation specification for a scroll decay animation
* using iOS-style decay behavior.
*
* @property decelerationRate The rate at which the velocity decelerates over time.
* Default value is equal to one used by default UIScrollView behavior.
*/
class CupertinoScrollDecayAnimationSpec(
private val decelerationRate: Float = UIScrollViewDecelerationRateNormal.toFloat()
) : FloatDecayAnimationSpec {

private val coefficient: Float = 1000f * ln(decelerationRate)

override val absVelocityThreshold: Float = 0.5f // Half pixel

override fun getTargetValue(initialValue: Float, initialVelocity: Float): Float =
initialValue - initialVelocity / coefficient

override fun getValueFromNanos(
playTimeNanos: Long,
initialValue: Float,
initialVelocity: Float
): Float {
val playTimeSeconds = convertNanosToSeconds(playTimeNanos).toFloat()
val initialVelocityOverTimeIntegral =
(decelerationRate.pow(1000f * playTimeSeconds) - 1f) / coefficient * initialVelocity
return initialValue + initialVelocityOverTimeIntegral
}

override fun getDurationNanos(initialValue: Float, initialVelocity: Float): Long {
val absVelocity = abs(initialVelocity)

if (absVelocity < absVelocityThreshold) {
return 0
}

val seconds = ln(-coefficient * absVelocityThreshold / absVelocity) / coefficient

return convertSecondsToNanos(seconds)
}

override fun getVelocityFromNanos(
playTimeNanos: Long,
initialValue: Float,
initialVelocity: Float
): Float {
val playTimeSeconds = convertNanosToSeconds(playTimeNanos).toFloat()

return initialVelocity * decelerationRate.pow(1000f * playTimeSeconds)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package androidx.compose.foundation.gestures

import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable

/**
Expand All @@ -42,4 +43,7 @@ interface FlingBehavior {
* @return remaining velocity after fling operation has ended
*/
suspend fun ScrollScope.performFling(initialVelocity: Float): Float
}
}

@Composable
internal expect fun rememberFlingBehavior(): FlingBehavior
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,7 @@ import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.animateDecay
import androidx.compose.animation.core.animateTo
import androidx.compose.animation.core.tween
import androidx.compose.animation.rememberSplineBasedDecay
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.MutatePriority
import androidx.compose.foundation.OverscrollEffect
import androidx.compose.foundation.focusGroup
import androidx.compose.foundation.*
import androidx.compose.foundation.gestures.Orientation.Horizontal
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.rememberOverscrollEffect
Expand Down Expand Up @@ -70,7 +66,6 @@ import androidx.compose.ui.util.fastForEach
import kotlin.math.abs
import kotlin.math.roundToInt
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
Expand Down Expand Up @@ -198,12 +193,7 @@ object ScrollableDefaults {
* Create and remember default [FlingBehavior] that will represent natural fling curve.
*/
@Composable
fun flingBehavior(): FlingBehavior {
val flingSpec = rememberSplineBasedDecay<Float>()
return remember(flingSpec) {
DefaultFlingBehavior(flingSpec)
}
}
fun flingBehavior(): FlingBehavior = rememberFlingBehavior()

/**
* Create and remember default [OverscrollEffect] that will be used for showing over scroll
Expand Down Expand Up @@ -412,7 +402,7 @@ private suspend fun ScrollingLogic.animatedDispatchScroll(
tryReceiveNext()?.let {
target += it
}
if (target.isAboutZero()) {
if (target.isLowScrollingDelta()) {
return
}
scrollableState.scroll {
Expand All @@ -433,17 +423,17 @@ private suspend fun ScrollingLogic.animatedDispatchScroll(
sequentialAnimation = true
) {
val delta = value - lastValue
if (!delta.isAboutZero()) {
if (!delta.isLowScrollingDelta()) {
val consumedDelta = scrollBy(delta)
if (!(delta - consumedDelta).isAboutZero()) {
if (!(delta - consumedDelta).isLowScrollingDelta()) {
cancelAnimation()
return@animateTo
}
lastValue += delta
}
tryReceiveNext()?.let {
target += it
requiredAnimation = !(target - lastValue).isAboutZero()
requiredAnimation = !(target - lastValue).isLowScrollingDelta()
cancelAnimation()
}
}
Expand Down Expand Up @@ -471,7 +461,12 @@ private fun Modifier.mouseWheelInput(

private inline val PointerEvent.isConsumed: Boolean get() = changes.fastAny { it.isConsumed }
private inline fun PointerEvent.consume() = changes.fastForEach { it.consume() }
private inline fun Float.isAboutZero(): Boolean = abs(this) < 0.5f

/*
* Returns true, if the value is too low for visible change in scroll (consumed delta, animation-based change, etc),
* false otherwise
*/
private inline fun Float.isLowScrollingDelta(): Boolean = abs(this) < 0.5f

private suspend fun AwaitPointerEventScope.awaitScrollEvent(): PointerEvent {
var event: PointerEvent
Expand All @@ -491,6 +486,7 @@ private class ScrollingLogic(
val overscrollEffect: OverscrollEffect?
) {
private val isNestedFlinging = mutableStateOf(false)

fun Float.toOffset(): Offset = when {
this == 0f -> Offset.Zero
orientation == Horizontal -> Offset(this, 0f)
Expand Down Expand Up @@ -571,49 +567,61 @@ private class ScrollingLogic(

val availableVelocity = initialVelocity.singleAxisVelocity()

val performFling: suspend (Velocity) -> Velocity = { velocity ->
val preConsumedByParent = nestedScrollDispatcher
.value.dispatchPreFling(velocity)
val available = velocity - preConsumedByParent
val velocityLeft = doFlingAnimation(available)
val consumedPost =
nestedScrollDispatcher.value.dispatchPostFling(
(available - velocityLeft),
velocityLeft
)
val totalLeft = velocityLeft - consumedPost
velocity - totalLeft
}
scrollableState.scroll {
val performFling: suspend (Velocity) -> Velocity = { velocity ->
val preConsumedByParent = nestedScrollDispatcher
.value.dispatchPreFling(velocity)
val available = velocity - preConsumedByParent
val velocityLeft = doFlingAnimation(available)
val consumedPost =
nestedScrollDispatcher.value.dispatchPostFling(
(available - velocityLeft),
velocityLeft
)
val totalLeft = velocityLeft - consumedPost
velocity - totalLeft
}

if (overscrollEffect != null && shouldDispatchOverscroll) {
overscrollEffect.applyToFling(availableVelocity, performFling)
} else {
performFling(availableVelocity)
if (overscrollEffect != null && shouldDispatchOverscroll) {
overscrollEffect.applyToFling(availableVelocity, performFling)
} else {
performFling(availableVelocity)
}
}

// Self stopped flinging, reset
registerNestedFling(false)
}

suspend fun doFlingAnimation(available: Velocity): Velocity {
suspend fun ScrollScope.doFlingAnimation(available: Velocity): Velocity {
var result: Velocity = available
scrollableState.scroll {
val outerScopeScroll: (Offset) -> Offset = { delta ->
dispatchScroll(delta.reverseIfNeeded(), Fling).reverseIfNeeded()
}
val scope = object : ScrollScope {
override fun scrollBy(pixels: Float): Float {
return outerScopeScroll.invoke(pixels.toOffset()).toFloat()
}

val outerScopeScroll: (Offset) -> Offset = { delta ->
dispatchScroll(delta.reverseIfNeeded(), Fling).reverseIfNeeded()
}
val scope = object : ScrollScope {
override fun scrollBy(pixels: Float): Float {
return outerScopeScroll.invoke(pixels.toOffset()).toFloat()
}
with(scope) {
with(flingBehavior) {
result = result.update(
performFling(available.toFloat().reverseIfNeeded()).reverseIfNeeded()
)
}
}
with(scope) {
with(flingBehavior) {
result = result.update(
performFling(available.toFloat().reverseIfNeeded()).reverseIfNeeded()
)
}
}

return result
}

suspend fun doFlingAnimationInNewScrollScope(available: Velocity): Velocity {
MatkovIvan marked this conversation as resolved.
Show resolved Hide resolved
var result: Velocity = available

scrollableState.scroll {
result = doFlingAnimation(available)
}

return result
}

Expand Down Expand Up @@ -683,7 +691,7 @@ private fun scrollableNestedScrollConnection(
available: Velocity
): Velocity {
return if (enabled) {
val velocityLeft = scrollLogic.value.doFlingAnimation(available)
val velocityLeft = scrollLogic.value.doFlingAnimationInNewScrollScope(available)
available - velocityLeft
} else {
Velocity.Zero
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package androidx.compose.foundation.gestures

import androidx.compose.animation.rememberSplineBasedDecay
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember

@Composable
internal actual fun rememberFlingBehavior(): FlingBehavior {
val flingSpec = rememberSplineBasedDecay<Float>()
return remember(flingSpec) {
DefaultFlingBehavior(flingSpec)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package androidx.compose.foundation.gestures

import androidx.compose.animation.rememberSplineBasedDecay
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember

@Composable
internal actual fun rememberFlingBehavior(): FlingBehavior {
val flingSpec = rememberSplineBasedDecay<Float>()
return remember(flingSpec) {
DefaultFlingBehavior(flingSpec)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package androidx.compose.foundation

import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.foundation.NoOpOverscrollEffect

@ExperimentalFoundationApi
@Composable
internal actual fun rememberOverscrollEffect(): OverscrollEffect = NoOpOverscrollEffect