Przeciąganie, przesuwanie i przesuwanie

Modyfikator draggable to ogólny punkt wejścia do przeciągania gestów w jednej orientacji. Raportuje odległość przeciągania w pikselach.

Pamiętaj, że ten modyfikator jest podobny do modyfikatora scrollable, ponieważ wykrywa tylko gest. Musisz przytrzymać stan i przedstawić go na ekranie, np. przesuwając element za pomocą modyfikatora offset:

@Composable
private fun DraggableText() {
    var offsetX by remember { mutableStateOf(0f) }
    Text(
        modifier = Modifier
            .offset { IntOffset(offsetX.roundToInt(), 0) }
            .draggable(
                orientation = Orientation.Horizontal,
                state = rememberDraggableState { delta ->
                    offsetX += delta
                }
            ),
        text = "Drag me!"
    )
}

Jeśli chcesz kontrolować cały gest przeciągania, użyj wzorca do wykrywania gestu przeciągania w modyfikatorze pointerInput.

@Composable
private fun DraggableTextLowLevel() {
    Box(modifier = Modifier.fillMaxSize()) {
        var offsetX by remember { mutableStateOf(0f) }
        var offsetY by remember { mutableStateOf(0f) }

        Box(
            Modifier
                .offset { IntOffset(offsetX.roundToInt(), offsetY.roundToInt()) }
                .background(Color.Blue)
                .size(50.dp)
                .pointerInput(Unit) {
                    detectDragGestures { change, dragAmount ->
                        change.consume()
                        offsetX += dragAmount.x
                        offsetY += dragAmount.y
                    }
                }
        )
    }
}

Element interfejsu przeciągany palcem.

Przesuwanie

Modyfikator swipeable umożliwia przeciąganie elementów, które po uwolnieniu są animowane do co najmniej 2 punktów zakotwiczenia zdefiniowanych w orientacji. Częstym zastosowaniem jest implementowanie wzorca „przesuwaj, aby zamknąć”.

Pamiętaj, że ten modyfikator nie porusza elementu, a jedynie wykrywa gest. Musisz przytrzymać stan i przedstawić go na ekranie, np. przesuwając element za pomocą modyfikatora offset.

Stan przesuwania jest wymagany w modyfikatorze swipeable. Można go utworzyć i zapamiętać za pomocą rememberSwipeableState(). Zapewnia on też zestaw przydatnych metod automatycznego animowania kotwic (patrz snapTo, animateTo, performFling i performDrag) oraz właściwości pozwalające obserwować postęp przeciągania.

Gesty przesuwania mogą mieć różne rodzaje progów, np. FixedThreshold(Dp) i FractionalThreshold(Float), a potem mogą być różne w zależności od kombinacji punktów zakotwiczenia.

Aby uzyskać większą elastyczność, możesz skonfigurować resistance podczas przesuwania poza granice oraz velocityThreshold, który będzie animować przesunięcie do następnego stanu, nawet jeśli pozycjonowanie thresholds nie zostanie osiągnięte.

@OptIn(ExperimentalMaterialApi::class)
@Composable
private fun SwipeableSample() {
    val width = 96.dp
    val squareSize = 48.dp

    val swipeableState = rememberSwipeableState(0)
    val sizePx = with(LocalDensity.current) { squareSize.toPx() }
    val anchors = mapOf(0f to 0, sizePx to 1) // Maps anchor points (in px) to states

    Box(
        modifier = Modifier
            .width(width)
            .swipeable(
                state = swipeableState,
                anchors = anchors,
                thresholds = { _, _ -> FractionalThreshold(0.3f) },
                orientation = Orientation.Horizontal
            )
            .background(Color.LightGray)
    ) {
        Box(
            Modifier
                .offset { IntOffset(swipeableState.offset.value.roundToInt(), 0) }
                .size(squareSize)
                .background(Color.DarkGray)
        )
    }
}

Element interfejsu reagujący na gest przesuwania