[英]Jetpack Compose LazyRow scroll with snap only to start of next or previous element
您可以像這樣檢查滾動方向
@Composable
private fun LazyListState.isScrollingUp(): Boolean {
var previousIndex by remember(this) { mutableStateOf(firstVisibleItemIndex) }
var previousScrollOffset by remember(this) { mutableStateOf(firstVisibleItemScrollOffset) }
return remember(this) {
derivedStateOf {
if (previousIndex != firstVisibleItemIndex) {
previousIndex > firstVisibleItemIndex
} else {
previousScrollOffset >= firstVisibleItemScrollOffset
}.also {
previousIndex = firstVisibleItemIndex
previousScrollOffset = firstVisibleItemScrollOffset
}
}
}.value
}
當然,您需要創建一個rememberLazyListState()
,然后將其作為參數傳遞給列表。
然后,根據滾動方向,您可以在協程中調用lazyListState.scrollTo(lazyListState.firstVisibleItemIndex + 1)
(如果用戶向右滾動),並適當地調用另一個方向。
(水平 LazyRow 的示例)
您可以滾動到下一個或上一個項目以創建快照效果。 檢查第一個可見項目的偏移量以查看列表中的哪個項目占用更多屏幕空間,然后向左或向右滾動到最可見的項目。
@Composable
fun SnappyLazyRow() {
val listState = rememberLazyListState()
val coroutineScope = rememberCoroutineScope()
LazyRow(
state = listState,
modifier = Modifier.fillMaxSize(),
content = {
items(/*list of items*/) { index ->
/* Item view */
if(!listState.isScrollInProgress){
if(listState.isHalfPastItemLeft())
coroutineScope.scrollBasic(listState, left = true)
else
coroutineScope.scrollBasic(listState)
if(listState.isHalfPastItemRight())
coroutineScope.scrollBasic(listState)
else
coroutineScope.scrollBasic(listState, left = true)
}
}
})
}
private fun CoroutineScope.scrollBasic(listState: LazyListState, left: Boolean = false){
launch {
val pos = if(left) listState.firstVisibleItemIndex else listState.firstVisibleItemIndex+1
listState.animateScrollToItem(pos)
}
}
@Composable
private fun LazyListState.isHalfPastItemRight(): Boolean {
return firstVisibleItemScrollOffset > 500
}
@Composable
private fun LazyListState.isHalfPastItemLeft(): Boolean {
return firstVisibleItemScrollOffset <= 500
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.