使用参数更新记忆值

发布于 2025-01-08 23:47:36 字数 1998 浏览 3 评论 0原文

我有一个可组合项,其中记住的值(偏移量)需要由可组合项本身和调用方(使用可组合项的参数)进行更新 - 我怎样才能实现这一点?

特别是,我有以下代码。我所说的值是 NavigableBox 中的 offset:我需要能够通过拖动框并使用 中的值手动设置它来控制它code>OffsetInputField 作为参数传递。

class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            Surface {
                Box {
                    var boxOffset by remember { mutableStateOf(Offset.Zero) }

                    NavigableBox(boxOffset)
                    OffsetInputField { offset ->
                        offset.toFloat().let { boxOffset = Offset(it, it) }
                    }
                }
            }
        }
    }
}

@Composable
fun OffsetInputField(onInput: (String) -> Unit) {
    var value by remember { mutableStateOf("") }

    TextField(
        value = value,
        onValueChange = { value = it },
        keyboardOptions = KeyboardOptions(imeAction = ImeAction.Go),
        keyboardActions = KeyboardActions(onGo = { onInput(value) })
    )
}

@Composable
fun NavigableBox(initOffset: Offset) {
    var offset by remember(initOffset) { mutableStateOf(initOffset) }

    Box(
        modifier = Modifier
            .fillMaxSize()
            .pointerInput(Unit) { detectTransformGestures { _, pan, _, _ -> offset += pan } }
    ) {
        Box(modifier = Modifier
            .size(100.dp)
            .offset { IntOffset(offset.x.roundToInt(), offset.y.roundToInt()) }
            .background(Color.Blue)
        )
    }
}

在当前的实现中,拖动工作正常,直到新值作为 OffsetInputField 的输入传递为止 - 然后框停止响应拖动。我认为这是因为包含偏移量的 MutableState 对象在重新计算时发生了变化,并且盒子不再观察它。

我已经尝试在 NavigableBox 中使用单向数据流(向其传递 offset 值和 onOffsetChange lambda,但随后拖动无法按预期工作:该框只是围绕其初始位置晃动,当手势停止时返回到它。

如果有人感兴趣,我正在开发一个应用程序,其中可拖动框是地图,文本字段用于搜索对象。它:地图移动到输入对象的中心。

I have a Composable in which a remembered value (an offset) needs to be updated both by the Composable itself and also from the calling side (using the Composable's arguments) -- how can I achieve this?

In particular, I have the following piece of code. The value I'm talking about is the offset in NavigableBox: I need to both be able to control it by dragging the box and by setting it manually using the value from OffsetInputField which is passed as an argument.

class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            Surface {
                Box {
                    var boxOffset by remember { mutableStateOf(Offset.Zero) }

                    NavigableBox(boxOffset)
                    OffsetInputField { offset ->
                        offset.toFloat().let { boxOffset = Offset(it, it) }
                    }
                }
            }
        }
    }
}

@Composable
fun OffsetInputField(onInput: (String) -> Unit) {
    var value by remember { mutableStateOf("") }

    TextField(
        value = value,
        onValueChange = { value = it },
        keyboardOptions = KeyboardOptions(imeAction = ImeAction.Go),
        keyboardActions = KeyboardActions(onGo = { onInput(value) })
    )
}

@Composable
fun NavigableBox(initOffset: Offset) {
    var offset by remember(initOffset) { mutableStateOf(initOffset) }

    Box(
        modifier = Modifier
            .fillMaxSize()
            .pointerInput(Unit) { detectTransformGestures { _, pan, _, _ -> offset += pan } }
    ) {
        Box(modifier = Modifier
            .size(100.dp)
            .offset { IntOffset(offset.x.roundToInt(), offset.y.roundToInt()) }
            .background(Color.Blue)
        )
    }
}

In the current implementation the dragging works fine until a new value is passed as OffsetInputField's input -- then the box stops responding to dragging. I assume it is because the MutableState object containing the offset changes when gets recalculated and the box doesn't observe it anymore.

I already tried using unidirectional data flow in NavigableBox (passing offset value and onOffsetChange lambda to it, but then dragging doesn't work as expected: the box just jiggles around its initial position, returning back to it when the gesture stops.

In case anyone interested, I'm developing an app where the draggable box is a map, and the text field is used for searching objects on it: the map is moved to be centered on an object entered.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

伪心 2025-01-15 23:47:36

pointerInput 捕获内部使用的所有状态变量。使用新的 initOffset 您将创建一个新的可变状态,但 pointerInput 会不断更新旧的引用。

您需要通过将相同的值传递给 key 来重新启动它:

pointerInput(initOffset) { /*...*/ }

pointerInput captures all the state variables used inside. With new initOffset you're creating a new mutable state, but pointerInput keeps updating the old reference.

You need to restart it by passing the same value(s) to key:

pointerInput(initOffset) { /*...*/ }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文