为什么 Compose 中的状态会重置?

问题描述 投票:0回答:1

我遇到了一个非常奇怪的问题。我正在制作一种方法来处理屏幕上的点击事件,因为我想将所有指针及其 id 和位置保存在地图中,我有一个状态类,其中有此地图,并且我正在使用ViewModel 中的方法

data class RandomState(
    val touchedPositions: Map<Long, Pair<Float, Float>> = emptyMap(),
)
fun updateTouchedPositions(
    touchedPositions: Map < Long, Pair < Float, Float >> 
) {
    println("Function from viewModel: $touchedPositions")
    state = state.copy(
        touchedPositions = touchedPositions)
}
.pointerInput(Unit) {
    awaitEachGesture {
        val positions = mutableMapOf < Long, Pair < Float, Float >> ()

        do {
            val event = awaitPointerEvent()
            val canceled = event.changes.fastAny {
                it.isConsumed
            }

            if (event.type == PointerEventType.Press) {
                event.changes.forEach { pointer - >
                    val id = pointer.id.value
                    val x = pointer.position.x
                    val y = pointer.position.y
                    positions[id] = Pair(x, y)
                }
                println("Se van a guardar las posiciones: $positions")
                viewModel.updateTouchedPositions(positions)
                println("Posiciones de dedos en onPress: ${state.touchedPositions}")
            }

            if (event.type == PointerEventType.Release) {
                println("Posiciones de dedos en onRelease: ${state.touchedPositions}")
            }

        } while (!canceled)
    }
}

问题是,尽管调试一切似乎都很好,但当我在 do 块的 if 内进行第二次打印时,state.touchedPositions 为空。就好像状态类以某种方式重置为默认状态,但我不知道为什么。

android kotlin android-jetpack-compose state
1个回答
0
投票

从您提供的代码中,尚不清楚

state
是什么以及如何在
pointerInput
中访问它,因此以下内容包括一些猜测工作。

pointerInput
是一个可组合函数,当可组合函数访问的任何状态发生更改时,通常会重新组合。然而,
pointerInput
明确定义了另一种行为:与
remember
LaunchedEffect
一样,它仅在key参数更改时重新组合。由于您提供了
Unit
作为键,因此当可组合项进入组合时,
pointerInput
只会执行一次。然后它捕获闭包中所需的所有变量。这就像变量当前包含的所有对象的快照。
state
就是这样一个将被捕获的对象,并且该对象将用于
pointerInput
内部发生的所有事情。

state
变量发生变化(可能是由于重组)时,闭包仍然只包含初始对象。由于您通过使用
Unit
决定永远不应该重组
pointerInput
,因此该闭包也永远不会用当前值刷新。因此,无论您对视图模型中的状态做什么,它都永远不会达到
pointerInput
lambda。

长话短说:您需要将

Unit
替换为
state

© www.soinside.com 2019 - 2024. All rights reserved.