Compose 中 交互事件处理

246 阅读2分钟

在 Jetpack Compose 中,事件处理(Handling)是指处理用户交互事件,如点击、滚动、拖拽等。Compose 提供了一组丰富的 API 来处理这些事件。下面将详细介绍如何在 Compose 中处理常见的用户交互事件,并提供相应的示例代码。

1. 点击事件处理 (Click Handling)

点击事件是最常见的用户交互之一。Compose 提供了 Modifier.clickable 用于处理点击事件。

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp

@Composable
fun ClickableExample() {
    var clicked by remember { mutableStateOf(false) }

    Box(
        modifier = Modifier
            .size(100.dp)
            .clickable { clicked = !clicked }
            .background(if (clicked) Color.Red else Color.Green)
    ) {
        Text(
            text = if (clicked) "Clicked!" else "Click me",
            color = Color.White
        )
    }
}

@Preview(showBackground = true)
@Composable
fun PreviewClickableExample() {
    ClickableExample()
}

2. 滚动事件处理 (Scroll Handling)

滚动事件处理使用 LazyColumnLazyRow 等组件来处理纵向和横向的滚动事件。

import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.tooling.preview.Preview

@Composable
fun ScrollExample() {
    val items = remember { List(100) { "Item #$it" } }

    LazyColumn {
        items(items) { item ->
            Text(text = item)
        }
    }
}

@Preview(showBackground = true)
@Composable
fun PreviewScrollExample() {
    ScrollExample()
}

3. 拖拽事件处理 (Drag Handling)

Compose 提供了 Modifier.draggableModifier.pointerInput 用于处理拖拽事件。

import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectDragGestures
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Surface
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp

@Composable
fun DragExample() {
    var offset by remember { mutableStateOf(Offset.Zero) }

    Box(
        modifier = Modifier
            .fillMaxSize()
            .pointerInput(Unit) {
                detectDragGestures { change, dragAmount ->
                    offset += Offset(dragAmount.x, dragAmount.y)
                    change.consume()
                }
            }
            .background(Color.LightGray)
    ) {
        Box(
            modifier = Modifier
                .offset { IntOffset(offset.x.roundToInt(), offset.y.roundToInt()) }
                .size(100.dp)
                .background(Color.Blue)
        )
    }
}

@Preview(showBackground = true)
@Composable
fun PreviewDragExample() {
    DragExample()
}

4. 滑动事件处理 (Swipe Handling)

可以使用 Modifier.swipeable 处理滑动事件,不过在 Compose 1.2.0 版本之后,建议使用 Modifier.draggable 来实现更复杂的滑动效果。

import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.rememberDraggableState
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Surface
import androidx.compose.runtime.*
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 kotlin.math.roundToInt

@Composable
fun SwipeExample() {
    var offsetX by remember { mutableStateOf(0f) }

    Box(
        modifier = Modifier
            .fillMaxSize()
            .draggable(
                orientation = Orientation.Horizontal,
                state = rememberDraggableState { delta ->
                    offsetX += delta
                }
            )
            .background(Color.LightGray)
    ) {
        Box(
            modifier = Modifier
                .offset { IntOffset(offsetX.roundToInt(), 0) }
                .size(100.dp)
                .background(Color.Blue)
        )
    }
}

@Preview(showBackground = true)
@Composable
fun PreviewSwipeExample() {
    SwipeExample()
}

结论

通过以上示例代码,我们展示了如何在 Jetpack Compose 中处理常见的用户交互事件,包括点击、滚动、拖拽和滑动事件。Compose 提供了简洁而强大的 API,使得处理这些事件变得非常容易。在实际应用中,您可以根据具体需求调整和扩展这些事件处理逻辑,以实现更复杂的交互效果。