[Day4] Jetpack Compose: 要如何让元件和我们来点互动?

知道怎麽构建UI後,我们来学学怎麽跟UI的互动

clickable

最简单的方式就是新增Modifier.clickable,比如说新增text被点击事件:

Text(
    text = "123",
    modifier = Modifier.clickable { Log.d("clickable", "click!") }
)

点击之後就会出现:

D/clickable: click!

那如果搭配昨天的mutableStateOf的使用方式:

val count = remember { mutableStateOf(0) }
Text(
    text = count.value.toString(),
    modifier = Modifier.clickable { count.value += 1 }
)

记得第一行要在composable的范围里面,不能宣告成一般kotlin的全域或区域变数,那我们就完成了一个每点一下就会加一的计数器++++++

pointerInput

如果想要实现原本的onTouchEvent能完成的事件侦测,那可以使用Modifier.pointerInput来完成,里面则是依照需求放入PointerInputScope.detectTapGestures或 PointerInputScope.detectDragGestures:

点击侦测:

Modifier.pointerInput(Unit) {
    detectTapGestures(
        onPress = { /* Called when the gesture starts */ },
        onDoubleTap = { /* Called on Double Tap */ },
        onLongPress = { /* Called on Long Press */ },
        onTap = { /* Called on Tap */ }
    )
}

拖动效果:

suspend fun PointerInputScope.detectDragGestures(
    onDragStart: (Offset) -> Unit = { },
    onDragEnd: () -> Unit = { },
    onDragCancel: () -> Unit = { },
    onDrag: (PointerInputChange, Offset) -> Unit
): Unit

或是我们可以使用底下的code来实现横向的拖动:

var offsetX by remember { mutableStateOf(0f) }
Text(modifier = Modifier
    .offset {
        IntOffset(offsetX.roundToInt(), 0)
    }
    .draggable(
        orientation = Orientation.Horizontal,
        state = rememberDraggableState(onDelta = { delta ->
            offsetX += delta
        }
        )
    ),
    text = "Drag me!")

offset可以实现元件的偏移位置,因为我们只移动X轴,所以y轴维持0,X轴的位置则是从offsetX.roundToInt()来读取,然後使用rememberDraggableState来更新拖动的位置。

swiping

有时候会有需要实作功能开关,或者非连续的状态切换的话,可以使用swiping来达成这个目标,同时我们也可以设定当滑动过半的时候,使用anchors让要活动的对象直接切换到对应的位:

swipeableState:通过 swipeableState 的设置可以获得现在元件移动到哪里
anchors:可以设置在不同状态时所对应的不偏移量,
orientation:手势的方向

於是我们时现的方式就来了:

val width = 200.dp
val squareSize = 100.dp

val swipeableState = rememberSwipeableState(0)
val sizePx = with(LocalDensity.current) { squareSize.toPx() }
val anchors = mapOf(0f to 0, sizePx to 1)

Box(
    modifier = Modifier
        .width(width)
        .swipeable(
            state = swipeableState,
            anchors = anchors,
            orientation = Orientation.Horizontal
        )
        .background(Color.LightGray)
) {
    Box(
        Modifier
            .offset { IntOffset(swipeableState.offset.value.roundToInt(), 0) }
            .size(squareSize)
            .background(Color.DarkGray)
    )
}

with(LocalDensity.current) { 16.dp.toPx() } 可以先当作把dp转成px的一种方式,然後开关的判断方式,是利用我们定义的anchors来决定是0还是1,这样我们定义的box就会利用offset对应到0或者是1的位置。


<<:  数位化世界

>>:  [Day 04] 测试驱动开发

Day 27 权限宝石:IAM Group 建立与使用

今天我们要来介绍 IAM Group 的建立与使用,那我们开始吧! IAM Group 建立 首先...

Gulp 基础介绍 DAY79

今天我们要先来介绍 Gulp 基本的四个 API 提供使用 gulp.task 执行工作 gulp....

Day 12 Classify images with the Custom Vision service

Some potential uses - Product identification, disa...

微不足道的小事,才真正走进我们心里,累积成了生命中难忘的美好风景。

过去十年,我的人生可以用两个字来形容,很多时候都是在:忙录。(或是瞎忙XD) 从小就被教育要以考高分...

前端工程师也能开发全端网页:挑战 30 天用 React 加上 Firebase 打造社群网站|Day8 文章主题列表

连续 30 天不中断每天上传一支教学影片,教你如何用 React 加上 Firebase 打造社群...