)
我们上面所罗列的这些拖动 API 只提供了监听 UI 组件拖动的能力,我们可以根据需求为其拓展功能,这也是这些API所存在的意义。我们从字面上就可以看出每个 API 所对应的含义,由于这些API的功能与参数相近,这里我们仅以 detectDragGestures
作为举例说明。
举例说明
接下来我们将完成一个绿色方块的手势拖动。在 Draggabel Modifier
中我们还只能监听垂直或水平中某一个方向的手势拖动,而使用 detectDragGestures
所有手势信息都是可以拿到的。如果我们还是只希望拿到某一个方向的手势拖动,使用 detectHorizontalDragGestures
或 detectVerticalDragGestures
即可,当然我们也可以使用 detectDragGestures
并且忽略掉某个方向的手势信息。如果我们希望在长按后才能拿到手势信息可以使用 detectDragGesturesAfterLongPress
。
detectDragGestures
提供了四个参数。
onDragStart (可选):拖动开始时回调
onDragEnd (可选):拖动结束时回调
onDragCancel (可选):拖动取消时回调
onDrag (必须):拖动时回调
decectDragGestures
的源码分析在 awaitTouchSlopOrCancellation 小节会有讲解。
suspend fun PointerInputScope.detectDragGestures(
onDragStart: (Offset) -> Unit = { },
onDragEnd: () -> Unit = { },
onDragCancel: () -> Unit = { },
onDrag: (change: PointerInputChange, dragAmount: Offset) -> Unit
)
💡 Tips
有些同学可能困惑
onDragCancel
触发时机。在一些场景中,当组件拖动时会根据事件分发顺序进行事件分发,当前面先处理事件的组件满足了设置的消费条件,导致手势事件被消费,导致本组件拿到的是被消费的手势事件,从而会执行onDragCancel
回调。如何定制事件分发顺序并消费事件后续会进行详细的描述。
示例如下所示
@Preview
@Composable
fun DragGestureDemo() {
var boxSize = 100.dp
var offset by remember { mutableStateOf(Offset.Zero) }
Box(contentAlignment = Alignment.Center,
modifier = Modifier.fillMaxSize()
) {
Box(Modifier
.size(boxSize)
.offset {
IntOffset(offset.x.roundToInt(), offset.y.roundToInt())
}
.background(Color.Green)
.pointerInput(Unit) {
detectDragGestures(
onDragStart = { offset ->
// 拖动开始
},
onDragEnd = {
// 拖动结束
},
onDragCancel = {
// 拖动取消
},
onDrag = { change: PointerInputChange, dragAmount: Offset ->
// 拖动中
offset += dragAmount
}
)
}
)
}
}
点击类型基础 API
API 介绍
| API名称 | 作用 |
| — | — |
| detectTapGestures | 监听点击手势 |
与 Clickable Modifier
不同的是,detectTapGestures
可以监听更多的点击事件。作为手机监听的基础 API,必然不会存在 Clickable Modifier
所拓展的涟漪效果。
举例说明
接下来我们将为一个绿色方块添加点击手势处理逻辑。detectTapGestures
提供了四个可选参数,用来监听不同点击事件。
onDoubleTap (可选):双击时回调
onLongPress (可选):长按时回调
onPress (可选):按下时回调
<