android Jetpack合成导航结果

6rvt4ljy  于 2022-12-16  发布在  Android
关注(0)|答案(5)|浏览(259)

我正在使用Jetpack Navigation库的合成版本。我正在设置导航,就像here显示的那样
我希望能够从屏幕A导航到屏幕B。一旦B执行某项操作并从后台堆栈弹出,它将返回屏幕A可以访问的结果。
我发现了一种使用Activities here来完成此操作的方法,但我希望避免创建任何额外的Activity,并在compose中完成此操作。

wvmv3b1j

wvmv3b1j1#

从要返回数据的可组合文件中,可以执行以下操作:

navController.previousBackStackEntry
    ?.savedStateHandle
    ?.set("your_key", "your_value")
navController.popBackStack()

然后从源Composable中,可以使用LiveData侦听更改。

val secondScreenResult = navController.currentBackStackEntry
    ?.savedStateHandle
    ?.getLiveData<String>("your_key")?.observeAsState()
...
secondScreenResult?.value?.let {
    // Read the result
}
bogh5gae

bogh5gae2#

如果只需要一次获取值,则需要在使用后删除值:

val screenResultState = navController.currentBackStackEntry
    ?.savedStateHandle
    ?.getLiveData<String>("some_key")?.observeAsState()

screenResultState?.value?.let {
    ...
    // make something, for example `viewModel.onResult(it)`
    ...
    //removing used value
    navController.currentBackStackEntry
        ?.savedStateHandle
        ?.remove<String>("some_key")
}

我还在函数中提取它(用于JetPack合成)

@Composable
fun <T> NavController.GetOnceResult(keyResult: String, onResult: (T) -> Unit){
    val valueScreenResult =  currentBackStackEntry
        ?.savedStateHandle
        ?.getLiveData<T>(keyResult)?.observeAsState()

    valueScreenResult?.value?.let {
        onResult(it)
       
        currentBackStackEntry
            ?.savedStateHandle
            ?.remove<T>(keyResult)
    }
}

您可以将其复制到您的项目中,并按如下方式使用:

navController.GetOnceResult<String>("some_key"){
    ...
    // make something
}
oug3syen

oug3syen3#

对于jetpack合成,必须将FlowcollectAsState一起使用才能获得结果:

navController.currentBackStackEntry
?.savedStateHandle?.getStateFlow<Boolean?>("refresh", false)
?.collectAsState()?.value?.let {
if (it)screenVM.refresh() }

您也可以删除条目,并在screenVM.refresh()后添加此条目:

navController.currentBackStackEntry
                ?.savedStateHandle ?.set("refresh", false)
bhmjp9jg

bhmjp9jg4#

不使用LiveData或Flow也可以得到结果,可以使用savedStateHandle.remove方法,我认为这是更简单的方法:

val secondResult = appNavController.currentBackStackEntry?.savedStateHandle?.remove<Data?>("data")
    secondResult?.let { data ->
        Log.d(TAG, "Data result: $data")
    }
gv8xihay

gv8xihay5#

val navController = rememberNavController()
composable("A") {
    val viewmodel: AViewModel = hiltViewModel()
    AScreen()
}
composable("B") {
    val viewmodel: BViewModel = hiltViewModel()
    val previousViewmodel: AViewModel? = navController
        .previousBackStackEntry?.let {
            hiltViewModel(it)
        }
    BScreen(
       back = { navController.navigateUp() },
       backWhitResult = { arg ->
           previousViewmodel?.something(arg)
       }
    )
}

相关问题