An implementation of [LazyLayoutScrollScope] that can be used with LazyLists.
@Composable
@Preview
fun LazyGridCustomScrollUsingLazyLayoutScrollScopeSample() {
suspend fun LazyGridState.customScroll(block: suspend LazyLayoutScrollScope.() -> Unit) =
scroll {
block.invoke(LazyLayoutScrollScope(this@customScroll, this))
}
val itemsList = (0..100).toList()
val state = rememberLazyGridState()
val scope = rememberCoroutineScope()
Column(Modifier.verticalScroll(rememberScrollState())) {
Button(
onClick = {
scope.launch {
state.customScroll {
snapToItem(40, 0) // teleport to item 40
val distance = calculateDistanceTo(50).toFloat()
var previousValue = 0f
androidx.compose.animation.core.animate(
0f,
distance,
animationSpec = tween(5_000),
) { currentValue, _ ->
previousValue += scrollBy(currentValue - previousValue)
}
}
}
}
) {
Text("Scroll To Item 50")
}
LazyHorizontalGrid(
state = state,
rows = GridCells.Fixed(3),
modifier = Modifier.height(600.dp).fillMaxWidth(),
) {
items(itemsList) {
Box(Modifier.padding(2.dp).background(Color.Red).size(45.dp)) {
Text(it.toString())
}
}
}
}
}
@Composable
@Preview
fun LazyListCustomScrollUsingLazyLayoutScrollScopeSample() {
suspend fun LazyListState.customScroll(block: suspend LazyLayoutScrollScope.() -> Unit) =
scroll {
block.invoke(LazyLayoutScrollScope(this@customScroll, this))
}
val itemsList = (0..100).toList()
val state = rememberLazyListState()
val scope = rememberCoroutineScope()
Column(Modifier.verticalScroll(rememberScrollState())) {
Button(
onClick = {
scope.launch {
state.customScroll {
snapToItem(40, 0) // teleport to item 40
val distance = calculateDistanceTo(50).toFloat()
var previousValue = 0f
androidx.compose.animation.core.animate(
0f,
distance,
animationSpec = tween(5_000),
) { currentValue, _ ->
previousValue += scrollBy(currentValue - previousValue)
}
}
}
}
) {
Text("Scroll To Item 50")
}
LazyRow(state = state) {
items(itemsList) {
Box(Modifier.padding(2.dp).background(Color.Red).size(45.dp)) {
Text(it.toString())
}
}
}
}
}
@Composable
@Preview
fun LazyStaggeredGridCustomScrollUsingLazyLayoutScrollScopeSample() {
suspend fun LazyStaggeredGridState.customScroll(
block: suspend LazyLayoutScrollScope.() -> Unit
) = scroll { block.invoke(LazyLayoutScrollScope(this@customScroll, this)) }
val itemsList = (0..100).toList()
val state = rememberLazyStaggeredGridState()
val scope = rememberCoroutineScope()
Column(Modifier.verticalScroll(rememberScrollState())) {
Button(
onClick = {
scope.launch {
state.customScroll {
snapToItem(40, 0) // teleport to item 40
val distance = calculateDistanceTo(50).toFloat()
var previousValue = 0f
androidx.compose.animation.core.animate(
0f,
distance,
animationSpec = tween(5_000),
) { currentValue, _ ->
previousValue += scrollBy(currentValue - previousValue)
}
}
}
}
) {
Text("Scroll To Item 50")
}
LazyHorizontalStaggeredGrid(
state = state,
rows = StaggeredGridCells.Fixed(3),
modifier = Modifier.height(600.dp).fillMaxWidth(),
) {
items(itemsList) {
Box(Modifier.padding(2.dp).background(Color.Red).size(45.dp)) {
Text(it.toString())
}
}
}
}
}
@Preview
@Composable
fun PagerCustomScrollUsingLazyLayoutScrollScopeSample() {
suspend fun PagerState.customScroll(block: suspend LazyLayoutScrollScope.() -> Unit) = scroll {
block.invoke(LazyLayoutScrollScope(this@customScroll, this))
}
val itemsList = (0..100).toList()
val state = rememberPagerState { itemsList.size }
val scope = rememberCoroutineScope()
Column(Modifier.verticalScroll(rememberScrollState())) {
Button(
onClick = {
scope.launch {
state.customScroll {
snapToItem(40, 0) // teleport to item 40
val distance = calculateDistanceTo(50).toFloat()
var previousValue = 0f
androidx.compose.animation.core.animate(
0f,
distance,
animationSpec = tween(5_000),
) { currentValue, _ ->
previousValue += scrollBy(currentValue - previousValue)
}
}
}
}
) {
Text("Scroll To Item 50")
}
HorizontalPager(state) {
Box(Modifier.padding(2.dp).background(Color.Red).height(600.dp).fillMaxWidth()) {
Text(itemsList[it].toString())
}
}
}
}