【问题标题】:How to navigate on view model field change in Compose Navigation?如何在 Compose Navigation 中导航视图模型字段更改?
【发布时间】:2021-11-25 16:47:59
【问题描述】:

在我的应用程序中,我想向服务器发送信息,并在收到成功的响应后,我想将信息传递到当前屏幕以导航到另一个屏幕。

流程如下:

从 UI 我调用 viewModel 向服务器发送请求。在ViewModel我有一个回调:

@HiltViewModel
class CreateAccountViewModel @Inject constructor(
    private val cs: CS
) : ViewModel() {

    private val _screen = mutableStateOf("")

    val screen: State<String> = _screen

    fun setScreen(screen: Screen) {
        _screen.value = screen.route
    }

    private val signUpCallback = object : SignUpHandler {
        override fun onSuccess(user: User?, signUpResult: SignUpResult?) {
            setScreen(Screen.VerifyAccountScreen)
            Log.i(Constants.TAG, "sign up success")

        }

        override fun onFailure(exception: Exception?) {
            Log.i(Constants.TAG, "sign up failure ")
        }

    }
}

如您所见,我也有State 负责屏幕,所以当响应成功时,我想更新状态,以便 UI 层(屏幕)知道它应该导航到另一个屏幕。我的问题是:我如何在

中观察状态
@Composable
fun CreateAccountScreen(
    navController: NavController,
    viewModel: CreateAccountViewModel = hiltViewModel()
) {
}

或者有没有更好的方法来实现这一点?

【问题讨论】:

    标签: android kotlin android-jetpack-compose android-viewmodel


    【解决方案1】:

    我认为您的视图模型应该对导航路线一无所知。在这种情况下,简单的verificationNeeded 标志就足够了:

    var verificationNeeded by mutableStateOf(false)
        private set
    
    private val signUpCallback = object : SignUpHandler {
        override fun onSuccess(user: User?, signUpResult: SignUpResult?) {
            verificationNeeded = true
            Log.i(Constants.TAG, "sign up success")
        }
    
        override fun onFailure(exception: Exception?) {
            Log.i(Constants.TAG, "sign up failure ")
        }
    }
    

    最佳实践是不要在管理NavHost 的视图之外共享navController,并且只传递偶数处理程序。当您需要测试或预览屏幕时,它可能会很有用。

    以下是更改此标志时的导航方式:

    @Composable
    fun CreateAccountScreen(
        onRequestVerification: () -> Unit,
        viewModel: CreateAccountViewModel = hiltViewModel(),
    ) {
        if (viewModel.verificationNeeded) {
            LaunchedEffect(Unit) {
                onRequestVerification()
            }
        }
    }
    

    在您的导航管理视图中:

    val navController = rememberNavController()
    NavHost(
        navController = navController,
        startDestination = Screen.CreateAccount
    ) {
        composable(Screen.CreateAccount) {
            CreateAccountScreen(
                onRequestVerification = {
                    navController.navigate(Screen.VerifyAccountScreen)
                }
            )
        }
    }
    

    【讨论】:

    • 谢谢!这就是我要找的:)
    猜你喜欢
    • 2012-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-29
    • 2020-11-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多