使用参数更新记忆值
我有一个可组合项,其中记住的值(偏移量)需要由可组合项本身和调用方(使用可组合项的参数)进行更新 - 我怎样才能实现这一点?
特别是,我有以下代码。我所说的值是 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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
pointerInput
捕获内部使用的所有状态变量。使用新的initOffset
您将创建一个新的可变状态,但pointerInput
会不断更新旧的引用。您需要通过将相同的值传递给
key
来重新启动它:pointerInput
captures all the state variables used inside. With newinitOffset
you're creating a new mutable state, butpointerInput
keeps updating the old reference.You need to restart it by passing the same value(s) to
key
: