如何绑定ViewModel生命周期来撰写

Moh*_*mad 8 viewmodel android-lifecycle kotlin android-jetpack-compose

我现在正在使用 Jetpack Compose。我意识到我可以在可组合项中使用 ViewModel 并在可组合项中初始化视图模型,如下所示:

val myViewModel:MyViewModel = viewModel()
Run Code Online (Sandbox Code Playgroud)

但存在一个问题,即使未显示可组合项,这些视图模型也永远不会被销毁。

例如,我有一个主可组合屏幕,它根据用户交互加载一些其他屏幕,如下所示:

@Composable
fun MainAuthentication(viewModel: MainViewModel) {
    val state = viewModel.state.value
    val scope = rememberCoroutineScope()
    val scaffoldState = rememberScaffoldState()
    Scaffold(scaffoldState = scaffoldState)
    {

        //--------------------(login and sign up button)--------------------//
        Row(
            modifier = Modifier
                .padding(top = 50.dp)
                .fillMaxSize(),
            verticalAlignment = Alignment.CenterVertically,
        ) {
            if (!state.signUpFormIsVisible && !state.loginFormIsVisible) {
                Button(
                    onClick = {
                        viewModel.onEvent(event = MainEvent.LoginButtonClick)
                    },
                    modifier = Modifier
                        .padding(10.dp)
                        .weight(0.5f)
                ) {
                    Text(text = stringResource(id = R.string.login))
                }

                Button(
                    onClick = { viewModel.onEvent(event = MainEvent.SignUpButtonClick) },
                    modifier = Modifier
                        .padding(10.dp)
                        .weight(0.5f)
                ) {
                    Text(text = stringResource(id = R.string.signup))
                }
            }

        }



        LoginForm(show = state.loginFormIsVisible) { msg ->
            scope.launch {
                scaffoldState.snackbarHostState.showSnackbar(
                    message = msg
                )
            }
        }
        SignUpForm(show = state.signUpFormIsVisible) { msg ->
            scope.launch {
                scaffoldState.snackbarHostState.showSnackbar(
                    message = msg
                )
            }
        }


    }
}

Run Code Online (Sandbox Code Playgroud)

每个登录和注册屏幕都有其视图模型,其使用方式如下:

@Composable
fun LoginForm(show: Boolean, snackBarMsg: (String) -> Unit) {

    val viewModel: LoginViewModel = viewModel()
    val state = viewModel.state.value
 ...

AnimatedVisibility(
        visible = show,
        enter = slideInVertically(),
        exit = slideOutVertically()
    ) {
    ...
    ...
    }
}
Run Code Online (Sandbox Code Playgroud)

如果可组合项不可见,视图模型被破坏,如何将每个视图模型绑定到其可组合函数?

如果相应的可组合项不可见,销毁视图模型是一个好习惯吗?

Phi*_*hov 4

在 Compose 中,您可以使用navigation,这非常适合您的需求:每个路线都有自己的视图模型范围,一旦从导航返回堆栈中删除路线,该范围就会被销毁。

您可以popBackStack在导航到新屏幕之前从堆栈中删除当前屏幕,旧屏幕将随相应的视图模型一起被销毁。查看此答案,了解如何删除多个项目。

Compose Navigation 基于常规 Android 导航,因此它的文档与大多数问题相关,以防您觉得 Compose Navigation 文档很短。