在android jetpack compose中如何同时实现点击和拖动
时间: 2024-02-24 18:55:35 浏览: 234
Zoomable:通过对Jetpack Compose的拖动支持,轻松放大和缩小
在 Android Jetpack Compose 中,可以将点击和拖动的功能分别封装成 Clickable 和 Draggable 两个 Composable 函数,并将它们组合起来使用,实现同时实现点击和拖动的效果。
Clickable Composable 函数用于监听点击事件,返回一个布尔值表示是否消耗了点击事件。
```kotlin
@Composable
fun Clickable(
onClick: () -> Unit,
children: @Composable () -> Unit
) {
val state = remember { mutableStateOf(false) }
val gesture = remember { MutableInteractionSource() }
val clickableModifier = Modifier.pointerInput(Unit) {
detectTapGestures(
onPress = { state.value = true },
onRelease = { if (state.value) onClick() },
onCancel = { state.value = false },
onTap = { state.value = false }
)
gesture.tryAwaitRelease()
}
Box(
modifier = clickableModifier,
propagateMinConstraints = true,
propagateMaxConstraints = true
) {
children()
}
}
```
Draggable Composable 函数用于监听拖动事件,返回拖动后的位置。
```kotlin
@Composable
fun Draggable(
state: DragState,
onDrag: (Offset) -> Unit,
children: @Composable () -> Unit
) {
val offsetX = state.position.x
val offsetY = state.position.y
val density = LocalDensity.current.density
val draggableModifier = Modifier.pointerInput(Unit) {
detectDragGestures(
onDragStart = { state.isDragging = true },
onDragEnd = { state.isDragging = false },
onDrag = { change, dragAmount ->
state.position += dragAmount / density
onDrag(state.position)
change.consumePositionChange()
}
)
}
Box(
modifier = draggableModifier.offset { IntOffset(offsetX.roundToInt(), offsetY.roundToInt()) },
propagateMinConstraints = true,
propagateMaxConstraints = true
) {
children()
}
}
class DragState(var isDragging: Boolean = false, var position: Offset = Offset.Zero)
```
使用 Clickable 和 Draggable 组合实现同时点击和拖动的效果。
```kotlin
@Composable
fun ClickableAndDraggable(
onClick: () -> Unit,
onDrag: (Offset) -> Unit,
children: @Composable () -> Unit
) {
val state = remember { DragState() }
Draggable(
state = state,
onDrag = onDrag,
children = {
Clickable(
onClick = onClick,
children = children
)
}
)
}
```
调用 ClickableAndDraggable 函数即可实现同时点击和拖动的效果。
```kotlin
var position by remember { mutableStateOf(Offset.Zero) }
ClickableAndDraggable(
onClick = { /* 处理点击事件 */ },
onDrag = { p -> position = p }
) {
Box(
Modifier
.background(Color.Red)
.size(50.dp)
) {
Text("Drag me!", Modifier.align(Alignment.Center))
}
}
```
阅读全文