No *_*eto 7 android side-effects android-jetpack-compose jetpack-compose-navigation
我遇到这个问题,当异步任务执行后给定状态更新时,我必须进行导航。我这样做是这样的:
At ViewModel.kt
fun executeRandomTask() {
viewModelScope.launch {
runAsyncTask()
state = Success
}
}
At Composable.kt
LaunchedEffect(viewModel.state) {
if(viewModel.state is Success) {
navController.navigate("nextScreen")
}
}
Run Code Online (Sandbox Code Playgroud)
然后在下一个屏幕中,我单击后退导航按钮 (onBackPressed),会发生什么情况,效果再次启动。所以我又回到了“nextScreen”。
当我执行下一个解决方法时:
DisposableEffect(viewModel.state) {
if(viewModel.state is Success) {
navController.navigate("nextScreen")
}
onDispose {
viewModel.state = null
}
}
Run Code Online (Sandbox Code Playgroud)
像这样,视图模型状态被清除,它也证明正在发生的事情是导航控制器破坏了前一个屏幕(不确定这是否是预期的行为)。
我不确定我应该做什么来避免这种情况,因为这是一种非常常见的情况,并且在达到某个状态后必须清除状态看起来很脏。
小智 3
我使用 SharedFlow 来发出这样的一次性事件
class MyViewModel : ViewModel() {
private val _eventFlow = MutableSharedFlow<OneTimeEvent>()
val eventFlow = _eventFlow.asSharedFlow()
private fun emitEvent(event: OneTimeEvent) {
viewModelScope.launch { _eventFlow.emit(event) }
}
}
Run Code Online (Sandbox Code Playgroud)
用于定义事件的密封类
sealed class OneTimeEvent {
object SomeEvent: OneTimeEvent()
}
Run Code Online (Sandbox Code Playgroud)
最后在屏幕中收集这样的流程
fun MyScreen(viewModel: MyViewModel = hiltViewModel()) {
LaunchedEffect(Unit) {
viewModel.eventFlow.collect { event ->
when(event){
SomeEvent -> {
//Do Something
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
因此,每当您的状态发生变化时,您都可以发出一些事件并在屏幕中对其采取操作。
| 归档时间: |
|
| 查看次数: |
2116 次 |
| 最近记录: |