簡體   English   中英

Jetpack Compose LazyRow 滾動僅捕捉到下一個或上一個元素的開始

[英]Jetpack Compose LazyRow scroll with snap only to start of next or previous element

有沒有辦法使用 Jetpack Compose 水平滾動以開始或指定上一個或下一個元素的 position?

在 RecyclerView 中快速滾動

您可以像這樣檢查滾動方向

@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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM