Jetpack Compose: обнаружение смахивания или перетаскивания двумя пальцами

Даже не знаю с чего начать, ничего подобного в Jetpack Compose еще не было реализовано. Как я могу сделать составной жест обнаружения двумя пальцами (или перетаскивания)? Желательно (но не обязательно) не потребляя их

2 ответа

Я придумал решение, которое стабильно работает. Мне пришлось отредактировать исходный код для detectVerticalDragGestures, чтобы подсчитать используемые указатели, а затем вернуть счетчик в качестве параметра в «onVerticalDrag» следующим образом:

      suspend fun PointerInputScope.detectAdvancedVerticalDragGestures(
    onDragStart: (Offset) -> Unit = { },
    onDragEnd: () -> Unit = { },
    onVerticalDrag: (event: PointerEvent, change: PointerInputChange, dragAmount: Float, pointerCount: Int) -> Unit
) {
    awaitEachGesture {
        val down = awaitFirstDown(requireUnconsumed = false)

        var overSlop = 0f
        val drag = awaitVerticalPointerSlopOrCancellation(down.id, down.type) { change, over ->
            change.consume()
            overSlop = over
        }

        if (drag != null) {
            onDragStart.invoke(drag.position)


            //Here's the block of code I added to return count
            //By the way, IM not sure which pointer returns the drag amount
            //but i think it returns the drag amount for the pointer
            //that had the first down event (that touched the screen first)
            val changes = currentEvent.changes.takeLast(2)
            val count: Int = if (changes.size == 1) {
                1
            } else if (changes.size == 2) {
                if (changes.last().id != changes.first().id) {
                    2
                } else {
                    1
                }
            } else {
                0
            }

            onVerticalDrag.invoke(currentEvent, drag, overSlop, count)
            if (verticalDrag(drag.id) {
                    onVerticalDrag(currentEvent, it, it.positionChange().y, count)
                    it.consume()
                }
            ) {
                onDragEnd()
            }
        }
    }
}

Это также должно работать для обнаруженияDragGestures или обнаруженияHorizontalDragGestures, если вы редактируете так же, как я. Надеюсь, это помогло.

Вы можете добиться мультитач, используяtransformableмодификатор на вашем составном. Что-то вроде этого:

      @Composable
fun TransformableSample() {
    // set up all transformation states
    var scale by remember { mutableStateOf(1f) }
    var rotation by remember { mutableStateOf(0f) }
    var offset by remember { mutableStateOf(Offset.Zero) }
    val state = rememberTransformableState { zoomChange, offsetChange, rotationChange ->
        scale *= zoomChange
        rotation += rotationChange
        offset += offsetChange
}
    Box(
        Modifier
            // apply other transformations like rotation and zoom
            // on the pizza slice emoji
            .graphicsLayer(
                scaleX = scale,
                scaleY = scale,
                rotationZ = rotation,
                translationX = offset.x,
                translationY = offset.y
            )
            // add transformable to listen to multitouch transformation events
            // after offset
            .transformable(state = state)
            .background(Color.Blue)
            .fillMaxSize()
    )
}

Дополнительную информацию о жестах Compose можно найти здесь.

Другие вопросы по тегам