לגרור, להחליק ולהזיז

draggable מקש הצירוף הוא נקודת הכניסה ברמה הכללית לגרירת תנועות בכיוון אחד, ומדווח על מרחק הגרירה בפיקסלים.

חשוב לציין שההתאמה הזו דומה ל-scrollable, כי היא מזהה רק את התנועה. צריך להחזיק את המצב ולייצג אותו במסך על ידי, לדוגמה, העברת הרכיב דרך 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!"
    )
}

אם צריך לשלוט בכל תנועת הגרירה, כדאי להשתמש בגרירה במקום זאת, באמצעות 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
                    }
                }
        )
    }
}

רכיב בממשק המשתמש שגוררים בלחיצה על האצבע

החלקה

swipeable מקש הצירוף מאפשר לגרור רכיבים אשר לאחר שחרורם, מונפשים אליהם שתי נקודות עוגן או יותר מוגדרות בכיוון. שימוש נפוץ לשם כך הוא כדי ליישם דפוס של 'החלקה לסגירה'.

חשוב לציין שההתאמה הזו לא מעבירה את הרכיב, אלא רק מזהה את התנועה. צריך להחזיק את המצב ולייצג אותו במסך באמצעות, לדוגמה, העברת הרכיב דרך offset לעיבוד טקסט.

המצב של מצב 'החלקה' הוא חובה בתכונת הצירוף swipeable, ואפשר ליצור אותו וזיכרון באמצעות rememberSwipeableState(). המצב הזה מספק גם קבוצה של שיטות שימושיות להנפשה פרוגרמטית כדי מודעות עוגן (ראו snapTo animateTo, performFling, וגם performDrag) וגם מאפיינים שבאמצעותם ניתן לצפות בהתקדמות הגרירה.

ניתן להגדיר לתנועת ההחלקה סוגי סף שונים, כמו FixedThreshold(Dp) וגם FractionalThreshold(Float), והם יכולים להיות שונים בכל שילוב של נקודות עוגן.

לשיפור הגמישות, ניתן להגדיר את resistance כשמחליקים על פני את גבולות העיר, וגם את velocityThreshold, שיגרום להנפשה של החלקה אל גם אם לא הגעתם thresholdsלמיקום הבא.

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

רכיב בממשק המשתמש שמגיב לתנועת החלקה