Activity 启动器(文件选择器)在单个事件中加载多次 - Jetpack compose
Activity Launcher(File picker) is loading multiple times in single event - Jetpack compose
我在 Jetpack Compose 中的 HorizontalPager 中使用文件选择器。当点击按钮加载相应的屏幕时,启动器被触发 2 次。
代码片段
var openFileManager by remember {
mutableStateOf(false)
}
if (openFileManager) {
launcher.launch("*/*")
}
Button(text = "Upload",
onClick = {
openFileManager = true
})
已编辑:首先,Ian 的观点是正确的,为什么不直接在 onClick 中启动它?我还假设您可能想用 true
false
值做更多事情。如果你只想启动,那么这些都是无用的。
当您点击并使 openFileManager
为真时,屏幕可以绘制多次,因此仅使用条件不会阻止它多次调用。
您可以用 LaunchedEffect
和 openFileManager
作为键来包装您的代码。 LaunchedEffect
块将 运行 仅当您的 openFileManager
更改时。
if (openFileManager) {
LaunchedEffect(openFileManager) {
launcher.launch("*/*")
}
}
你永远不应该在 @Composable
中存储如此重要的状态。如此重要的业务逻辑应该存储在更强大的容器中,例如 ViewModel
.
ViewModel{
var launch by mutableStateOf (false)
private set
fun updateLaunchValue(newValue: Boolean){
launch = newValue
}
}
将这些从主 activity
传递给 Composable
MyComposable(
launchValue = viewModel.launch
updateLaunchValue = viewModel::updateLaunchValue
)
根据需要在可组合项中创建参数
@Comoosable
fun Uploader(launchValue: Boolean, onUpdateLaunchValue: (Boolean) -> Unit){
LaunchedEffect (launchValue){
if (launchValue)
launcher.launch(...)
}
Button { // This is onClick
onUpdateLaunchValue(true) // makes the value true in the vm, updating state
}
}
如果您认为它过于复杂,那您就错了范式。这是在 Compose 或任何声明性范例中处理状态的推荐和正确的方式,真的 afaik。这保持代码干净,同时完全分离 UI 和数据层,允许 UI 和状态之间的受控交互以实现应用程序的完美行为。
我在 Jetpack Compose 中的 HorizontalPager 中使用文件选择器。当点击按钮加载相应的屏幕时,启动器被触发 2 次。
代码片段
var openFileManager by remember {
mutableStateOf(false)
}
if (openFileManager) {
launcher.launch("*/*")
}
Button(text = "Upload",
onClick = {
openFileManager = true
})
已编辑:首先,Ian 的观点是正确的,为什么不直接在 onClick 中启动它?我还假设您可能想用 true
false
值做更多事情。如果你只想启动,那么这些都是无用的。
当您点击并使 openFileManager
为真时,屏幕可以绘制多次,因此仅使用条件不会阻止它多次调用。
您可以用 LaunchedEffect
和 openFileManager
作为键来包装您的代码。 LaunchedEffect
块将 运行 仅当您的 openFileManager
更改时。
if (openFileManager) {
LaunchedEffect(openFileManager) {
launcher.launch("*/*")
}
}
你永远不应该在 @Composable
中存储如此重要的状态。如此重要的业务逻辑应该存储在更强大的容器中,例如 ViewModel
.
ViewModel{
var launch by mutableStateOf (false)
private set
fun updateLaunchValue(newValue: Boolean){
launch = newValue
}
}
将这些从主 activity
传递给 ComposableMyComposable(
launchValue = viewModel.launch
updateLaunchValue = viewModel::updateLaunchValue
)
根据需要在可组合项中创建参数
@Comoosable
fun Uploader(launchValue: Boolean, onUpdateLaunchValue: (Boolean) -> Unit){
LaunchedEffect (launchValue){
if (launchValue)
launcher.launch(...)
}
Button { // This is onClick
onUpdateLaunchValue(true) // makes the value true in the vm, updating state
}
}
如果您认为它过于复杂,那您就错了范式。这是在 Compose 或任何声明性范例中处理状态的推荐和正确的方式,真的 afaik。这保持代码干净,同时完全分离 UI 和数据层,允许 UI 和状态之间的受控交互以实现应用程序的完美行为。