我的应用程序中有两个屏幕:SCREEN_A和SCREEN_B
SCREEN_A→监听SCREEN_B的结果
@Composable
fun ScreenA() {
val result = currentBackStackEntry
?.savedStateHandle
?.getLiveData<String>("resultKey")
?.observeAsState()
result?.value?.let {
Log.d("AABBCCDDEE", "TESTING RESULT")
currentBackStackEntry
?.savedStateHandle
?.remove<String>("resultKey")
}
// ...
}
SCREEN_B→触发一个结果并从堆栈中弹出
@Composable
fun ScreenB() {
val coroutineScope = rememberCoroutineScope()
LaunchedEffect(key1 = Unit) {
scope.launch {
delay(3000)
navController.previousBackStackEntry
?.savedStateHandle
?.set("resultKey", "TESTING HERE : )")
navController.popBackStack()
}
}
}
问题是当应用程序从SCREEN_B导航回SCREEN_A时,结果被触发两次(字符串"TESTING results ">
我能做些什么来避免这种情况?
我认为这段代码已经足够了
currentBackStackEntry
?.savedStateHandle
?.remove<String>("resultKey")
在你的结果数据上最好使用getStateFlow
和LaunchedEffect
,这更适合和可组合的工作。
例如,您可以为NavController创建扩展,以封装逻辑
@Composable
fun <T> NavController.CollectDataResult(key: String, initialValue: T, result: (T) -> Unit) {
val resultState = currentBackStackEntry?.savedStateHandle
?.getStateFlow(key, initialValue)?.collectAsState()
LaunchedEffect(resultState) {
resultState?.value?.let {
result(it)
currentBackStackEntry?.savedStateHandle?.remove<T>(key)
}
}
}