Kefas
07/27/2021, 2:08 AManimateScrollBy
can be cancelled if I scroll the lazy column at the same time, and then the entire LaunchedEffect will be cancelled.
val scrollState = rememberLazyListState()
LaunchedEffect(Unit) {
while (true) {
delay(1000L)
scrollState.animateScrollBy(100f)
}
}
Kefas
07/27/2021, 2:10 AMval scrollState = rememberLazyListState()
var randomNumber by remember { mutableStateOf(0) }
LaunchedEffect(Unit) {
while (true) {
delay(1000L)
randomNumber = Random.nextInt()
}
}
LaunchedEffect(randomNumber) {
scrollState.animateScrollBy(100f)
}
Luis
07/27/2021, 2:13 AMLuis
07/27/2021, 2:14 AMKefas
07/27/2021, 2:19 AMscrollState
is not changed after scrolling, so it won't trigger the LaunchedEffect
again.
val scrollState = rememberLazyListState()
LaunchedEffect(scrollState) {
delay(1000L)
scrollState.animateScrollBy(100f)
}
Luis
07/27/2021, 2:33 AMisScrollInProgress
property that you can use to trigger itLuis
07/27/2021, 2:33 AMval scrollState = rememberLazyListState()
LaunchedEffect(scrollState.isScrollInProgress) {
if (scrollState.isScrollInProgress) return
delay(1000L)
scrollState.animateScrollBy(100f)
}
Albert Chang
07/27/2021, 3:16 AMisScrollInProgress
returns true for programmatical scroll as well so I don't think it will work.
Simply catching the CancellationException
should be enough:
LaunchedEffect(scrollState) {
while (true) {
delay(1000L)
runCatching { scrollState.animateScrollBy(100f) }
}
}
Kefas
07/27/2021, 3:19 AManimateScrollBy
will change the isScrollInProgress
state into true. I can remove the if (scrollState.isScrollInProgress) return
statement, but the delay will be run twice before it's actually scrollingLuis
07/27/2021, 3:58 AMLuis
07/27/2021, 3:59 AMAlbert Chang
07/27/2021, 4:03 AManimateScrollBy
is a suspend fun. It'll be canceled when the coroutine scope is canceled.Luis
07/27/2021, 4:09 AMKefas
07/27/2021, 4:15 AMCancellationException
which will break the coroutine cancellations.
I'll try to cancel the launched effect when animateScrollBy
is still running
https://twitter.com/Zhuinden/status/1389063911702470656Kefas
07/27/2021, 5:15 AMrunCatching
on a coroutine block, because the code inside LaunchedEffect
will still run even after it's cancelled.
https://gist.github.com/kefasjwiryadi/6c042a6874598ddee88e476ea4523793Albert Chang
07/27/2021, 5:23 AMLaunchedEffect(scrollState) {
while (isActive) {
delay(1000L)
runCatching { scrollState.animateScrollBy(100f) }
}
}
Kefas
07/27/2021, 7:32 AMlaunch
get cancelled, the parent's (LaunchedEffect) scope doesn't get cancelled.
LaunchedEffect(scrollState) {
while (true) {
delay(1000L)
launch {
scrollState.animateScrollBy(100f)
}
}
}
Luis
07/27/2021, 7:37 AMKefas
07/27/2021, 7:42 AMAlbert Chang
07/27/2021, 8:09 AMKefas
07/27/2021, 8:17 AMlaunch
matvei
07/27/2021, 1:25 PMscrollState
implements ScrollableState
interface, which supports priority based scroll. It's not available out of the box in animateScrollTo
, since disrupting and preventing user input is not something that should be easily accessible from the API design perspective. But it's doable if you really want it.
What you are looking for is suspend fun ScrollableState::scroll(priority:MutatePriority)
where you can choose the right priority and prevent user input and implement your own animation like so: https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:compose/[…]undation/gestures/ScrollExtensions.kt;l=35?q=ScrollExtensionsKefas
07/27/2021, 2:14 PM