簡體   English   中英

如何在撰寫導航中處理類似於 onActivityResult 的行為?

[英]How to handle behavior similar to onActivityResult in compose navigation?

我有一個設置,我想導航到結果的可組合項,然后根據該結果,我想從父項啟動另一個可組合項。 這是設置

ScreenA 為結果啟動 Screen B(用戶在 screenB 中執行某些操作)-> ScreenB 設置結果並將其自身從堆棧中彈出 -> ScreenA 查看結果並根據值啟動 ScreenC。

這里的問題是,一旦 ScreenB 設置了結果,我在結果上設置的觀察者就會無限觸發。

這是我的設置的簡化版本:

fun AppNavHost(
    navController: NavHostController
) {
    NavHost(
        navController = navController,
        startDestination = "ScreenA",
    ) {
        composable("ScreenA") {
            ScreenA(
                onClick = {
                    navController.navigate("ScreenB")
                }
            )
            val result = navController.currentBackStackEntry
                ?.savedStateHandle
                ?.getLiveData<String>("key")
                ?.observeAsState()
            result?.value?.let { str ->
                // This seems to not remove the key or at least
                // the live data value is not nulled out
                navController.currentBackStackEntry
                    ?.savedStateHandle
                    ?.remove<String>("key")
                if (str == "result") {
                    // This condition hits infinitely
                    navController.navigate("ScreenC")
                    // This logs infinitely
                    Log.d("TAG", "found result: $str")
                }
            }
        }
        composable("ScreenB") {
            ScreenB(
                onClick = {
                    navController.previousBackStackEntry
                        ?.savedStateHandle
                        ?.set("key", "result")
                    navController.popBackStack()
                }
            )
        }
        composable("ScreenC") { ScreenC() }
    }
}

我已經看過這個問題,我在這里的設置是相似的。 如何解決此問題,以便 ScreenB 的結果只讀取一次?

使用 LaunchedEffect 避免多次調用以在重組級別進行導航。

NavHost(
    navController = navController,
    startDestination = "ScreenA",
) {
    composable("ScreenA") {
        Button(
            onClick = {
                navController.navigate("ScreenB")
            },
            modifier = Modifier.padding(16.dp)
        ) {
            Text("Go to Screen B")
        }
        val result = navController.currentBackStackEntry
            ?.savedStateHandle
            ?.getLiveData<String>("key")
            ?.observeAsState()
        result?.value?.let { str ->
            navController.currentBackStackEntry
                ?.savedStateHandle
                ?.remove<String>("key")
            LaunchedEffect(str) {
                if (str == "result") {
                    navController.navigate("ScreenC")
                    Log.d("TAG", "found result: $str")
                }
            }
        }
    }
    composable("ScreenB") {
        Button(
            onClick = {
                navController.previousBackStackEntry
                    ?.savedStateHandle
                    ?.set("key", "result")
                navController.popBackStack()
            }
        ) {
            Text("Screen B")
        }
    }
     composable("ScreenC") { ScreenC() }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM