Петаскивание

Последнее обновление: 19.04.2024

Модификатор draggable() позволяет определить жесты перетаскивания на компоненте. Этот модификатор сохраняет смещение (или дельту) движения перетаскивания от исходной точки по мере его возникновения и сохраняет его в состоянии, которое создается с помощью функции rememberDraggableState(). Это состояние затем можно использовать, например, для перемещения перетаскиваемого компонента в соответствии с жестом. Определение функции модификатора:

Modifier.draggable(
    state: DraggableState,
    orientation: Orientation,
    enabled: Boolean = true,
    interactionSource: MutableInteractionSource? = null,
    startDragImmediately: Boolean = false,
    onDragStarted: suspend CoroutineScope.(startedPosition: Offset) -> Unit = {},
    onDragStopped: suspend CoroutineScope.(velocity: Float) -> Unit = {},
    reverseDirection: Boolean = false
)

Параметры модификатора:

  • state: состояние типа DraggableState, которое хранит информацию об операции перетаскивания.

  • orientation: направоение пертаскивания. Может быть горизонтальным (значение Orientation.Horizontal), либо вертикальным (Orientation.Vertical)

  • enabled: доступна ли операция перетаскивания

  • interactionSource: объект MutableInteractionSource, который будет использоваться для генерации DragInteraction.Start при начале перетаскивания.

  • startDragImmediately: если установлено значение true, то перетаскивание начнется немедленно. Предназначено для того, чтобы конечные пользователи могли "поймать" анимируемый компонент, нажав на него.

  • onDragStarted: suspend-функция, которая вызывает при начале перетаскивания

  • onDragStopped: suspend-функция, которая вызывает после завершения перетаскивания.

  • reverseDirection: изменяет направление прокрутки на обратное (прокрутка сверху вниз будет вести себя как снизу вверх, а слева направо — как справа налево).

При вызове модификатора draggable() необходимо указать как минимум два параиметра - состояние перемещения и его тип - по горизонтали или по вертикали.

Рассмотрим небольшой пример:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.draggable
import androidx.compose.foundation.gestures.rememberDraggableState
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Text

import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import kotlin.math.roundToInt


class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            var xOffset by remember { mutableStateOf(0f) }
            Column(Modifier.fillMaxSize()) {
                Box(
                    Modifier
                        .offset { IntOffset(xOffset.roundToInt(), 20) }
                        .background(Color.DarkGray)
                        .size(150.dp)
                        .draggable(
                            orientation = Orientation.Horizontal,
                            state = rememberDraggableState { distance ->
                                xOffset += distance
                            }
                        )
                )
                Text("xOffset: $xOffset", Modifier.padding(10.dp), fontSize=22.sp)
            }
        }
    }
}

В данном случае применяется перетаскивание по горизонтали. Для его отслеживания определяем сначала состояние xOffset:

var xOffset by remember { mutableStateOf(0f) }

Для перетаскивания определяем компонент Box, x-координата которого будет привязана к состоянию xOffset:

Box(
    Modifier
        .offset { IntOffset(xOffset.roundToInt(), 20) }

Далее к этому компоненту Box применяется модификатор draggable, который использует горизонтальную ориентацию. Параметр состояния устанавливается путем вызова функции rememberDraggableState(), в которой концевая лямбда-выражение используется для получения текущего значения дельты перемещения для получения обновленного состояния xOffset. Это, в свою очередь, приводит к перемещению поля в направлении жеста перетаскивания:

.draggable(
    orientation = Orientation.Horizontal,
    state = rememberDraggableState { distance ->
        xOffset += distance
    }
)

И для большей наглядности определен компонент Text, который выводит значение xOffset:

Обработка перетаскивания модификатор draggable в Jetpack Compose Kotlin Android
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850