簡體   English   中英

如何在 Jetpack Compose 中滾動部分?

[英]How can I scroll over sections in Jetpack Compose?

問題:

我有一個屏幕,其中一列充滿(太多)文本字段,這些文本字段可以打包成類別 - 使用戶更容易看到他正在使用的內容。


我的想法是我可以制作一種將文本字段放入其中的選項卡形式,然后只有用戶當前正在處理的選項卡是打開的,而其他選項卡是關閉但可見的。

我想讓它像一個垂直的視圖尋呼機,但你可以看到所有要滾動的元素。

要更改視圖,您可以滾動或單擊要訪問的類別。

只有一個選項卡將始終打開。

在此處輸入圖片說明

題:

但是我不知道這叫什么或者如何在 Jetpack Compose 中做到這一點 - 所以我想問一下是否有人可以指出我正確的方向。

您可以使用rememberSaveable存儲所選項目索引,然后您可以使用AnimatedVisibility為打開的視圖設置動畫。 要添加我創建的Modifier.swipeableTopBottom滑動,請在此答案中查看有關它如何工作的更多詳細信息。

var selectedItem by rememberSaveable { mutableStateOf(0) }
val itemsCount = 10
Column(
    verticalArrangement = Arrangement.spacedBy(10.dp),
    modifier = Modifier
        .padding(10.dp)
        .swipeableTopBottom(
            onTop = {
                selectedItem = (selectedItem - 1).coerceIn(0, itemsCount)
            },
            onBottom = {
                selectedItem = (selectedItem + 1).coerceIn(0, itemsCount)
            },
        )
) {
    repeat(itemsCount) { i ->
        Column(
            Modifier
                .clickable {
                    selectedItem = i
                }
                .fillMaxWidth()
                .background(Color.DarkGray)
                .padding(10.dp)
        ) {
            Text("Title $i")
            AnimatedVisibility(visible = i == selectedItem) {
                Column {
                    repeat(5) { j ->
                        Text("Subtitle $i $j")
                    }
                }
            }
        }
    }
}

Modifier.swipeableTopBottom

fun Modifier.swipeableTopBottom(onTop: () -> Unit, onBottom: () -> Unit): Modifier = composed {
    var width by rememberSaveable { mutableStateOf(0f) }
    val swipeableState = rememberSwipeableState(
        SwipeDirection.Initial,
        animationSpec = snap()
    )
    val anchorWidth = remember(width) {
        if (width == 0f) {
            1f
        } else {
            width
        }
    }
    val scope = rememberCoroutineScope()
    if (swipeableState.isAnimationRunning) {
        DisposableEffect(Unit) {
            onDispose {
                when (swipeableState.currentValue) {
                    SwipeDirection.Top -> {
                        onTop()
                    }
                    SwipeDirection.Bottom -> {
                        onBottom()
                    }
                    else -> {
                        return@onDispose
                    }
                }
                scope.launch {
                    swipeableState.snapTo(SwipeDirection.Initial)
                }
            }
        }
    }
    return@composed Modifier
        .onSizeChanged { width = it.width.toFloat() }
        .swipeable(
            state = swipeableState,
            anchors = mapOf(
                0f to SwipeDirection.Top,
                anchorWidth / 2 to SwipeDirection.Initial,
                anchorWidth to SwipeDirection.Bottom,
            ),
            thresholds = { _, _ -> FractionalThreshold(0.3f) },
            orientation = Orientation.Vertical
        )
}

private enum class SwipeDirection(val raw: Int) {
    Top(0),
    Initial(1),
    Bottom(2),
}

結果:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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