Ziehen, wischen und schleppen

Der Modifikator draggable ist der übergeordnete Einstiegspunkt für Ziegestreiche in einer einzigen Ausrichtung und gibt die Ziehdistanz in Pixeln an.

Dieser Modifikator ähnelt scrollable, da er nur die Geste erkennt. Sie müssen den Status beibehalten und auf dem Bildschirm darstellen, indem Sie das Element beispielsweise über den Modifikator offset bewegen:

@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!"
    )
}

Wenn Sie die gesamte Ziegestensteuerung benötigen, können Sie stattdessen den Ziegesten-Erkennungsmechanismus über den Modifikator pointerInput verwenden.

@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
                    }
                }
        )
    }
}

Ein UI-Element, das durch Drücken des Fingers verschoben wird

Wischen

Mit dem Modifikator swipeable können Sie Elemente ziehen, die sich nach dem Loslassen in der Regel zu zwei oder mehr in einer bestimmten Ausrichtung definierten Ankerpunkten animieren. Häufig wird dafür ein Wisch-zum-Schließen-Muster implementiert.

Dieser Modifikator bewegt das Element nicht, sondern erkennt nur die Geste. Sie müssen den Status beibehalten und auf dem Bildschirm darstellen, indem Sie das Element beispielsweise über den Modifikator offset bewegen.

Der Wischstatus ist im swipeable-Modifikator erforderlich und kann mit rememberSwipeableState() erstellt und gespeichert werden. Dieser Status bietet auch eine Reihe nützlicher Methoden, um Anker programmatisch zu animieren (siehe snapTo, animateTo, performFling und performDrag) sowie Eigenschaften, mit denen der Fortschritt des Ziehens beobachtet werden kann.

Für die Wischgeste können unterschiedliche Schwellentypen konfiguriert werden, z. B. FixedThreshold(Dp) und FractionalThreshold(Float). Sie können für jede Kombination von Start- und Zielpunkt des Ankerpunkts unterschiedlich sein.

Für mehr Flexibilität können Sie die resistance konfigurieren, wenn Sie über die Grenzen wischen, und auch die velocityThreshold, die ein Wischen zum nächsten Status animiert, auch wenn die thresholds für die Position nicht erreicht wurden.

@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)
        )
    }
}

Ein UI-Element, das auf Wisch-Touch-Gesten reagiert