使用参数更新记忆值
Update remembered value using arguments
我有一个可组合项,其中记忆值(偏移量)需要由可组合项本身和调用方(使用可组合项的参数)更新——我该如何实现?
特别是,我有以下代码。我说的值是 NavigableBox
中的 offset
:我需要能够通过拖动框和使用 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 传递给它,但是拖动没有按预期工作:盒子只是摇晃围绕它的初始位置,当手势停止时返回到它。
如果有人感兴趣,我正在开发一个应用程序,其中可拖动框是一张地图,文本字段用于搜索上面的对象:地图被移动到一个输入对象。
pointerInput
捕获里面使用的所有状态变量。使用新的 initOffset
您正在创建一个新的可变状态,但是 pointerInput
不断更新旧的引用。
您需要通过将相同的值传递给 key
:
来重新启动它
pointerInput(initOffset) { /*...*/ }
我有一个可组合项,其中记忆值(偏移量)需要由可组合项本身和调用方(使用可组合项的参数)更新——我该如何实现?
特别是,我有以下代码。我说的值是 NavigableBox
中的 offset
:我需要能够通过拖动框和使用 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 传递给它,但是拖动没有按预期工作:盒子只是摇晃围绕它的初始位置,当手势停止时返回到它。
如果有人感兴趣,我正在开发一个应用程序,其中可拖动框是一张地图,文本字段用于搜索上面的对象:地图被移动到一个输入对象。
pointerInput
捕获里面使用的所有状态变量。使用新的 initOffset
您正在创建一个新的可变状态,但是 pointerInput
不断更新旧的引用。
您需要通过将相同的值传递给 key
:
pointerInput(initOffset) { /*...*/ }