admin管理员组文章数量:1332865
What is the preferred way of instantiating a viewModel for a screen composable?
Option 1: inside the composable
eg 1.
@Composable
fun LoginScreen(
navController: NavController,
modifier: Modifier = Modifier,
loginViewModel: LoginViewModel = koinViewModel<LoginViewModel>()
){
}
eg 2.
@Composable
fun LoginScreen(
navController: NavController,
modifier: Modifier = Modifier,
) {
val loginViewModel = koinViewModel<LoginViewModel>()
}
I note that with this approach, it becomes impossible to show a preview of the screen on Android Studio, unless you create another composable that doesn't care about a viewModel and call it here. I don't want to do that.
Option 2: inside the navgraph, then pass an action lambda and state object
on the navigation graph:
composable(route = Screen.LoginScreen.route) {
val loginViewModel = koinViewModel<LoginViewModel>()
val state by loginViewModel.loginState.collectAsStateWithLifecycle()
LoginScreen(
navController = navController,
state = state,
onAction = { loginAction ->
loginViewModel.onAction(loginAction)
}
)
}
on the composable:
@Composable
fun LoginScreen(
navController: NavController,
modifier: Modifier = Modifier,
state: LoginState,
onAction: (LoginAction) -> Unit
){
}
With this approach, I am able to preview my LoginScreen composable. This however means I need to use actions for all possible UI actions, and pass my state as well. I don't mind this.
Now I am not sure according to best practices, which of these two would be the best approach? Could there be another recommended approach? Any pointers?
What is the preferred way of instantiating a viewModel for a screen composable?
Option 1: inside the composable
eg 1.
@Composable
fun LoginScreen(
navController: NavController,
modifier: Modifier = Modifier,
loginViewModel: LoginViewModel = koinViewModel<LoginViewModel>()
){
}
eg 2.
@Composable
fun LoginScreen(
navController: NavController,
modifier: Modifier = Modifier,
) {
val loginViewModel = koinViewModel<LoginViewModel>()
}
I note that with this approach, it becomes impossible to show a preview of the screen on Android Studio, unless you create another composable that doesn't care about a viewModel and call it here. I don't want to do that.
Option 2: inside the navgraph, then pass an action lambda and state object
on the navigation graph:
composable(route = Screen.LoginScreen.route) {
val loginViewModel = koinViewModel<LoginViewModel>()
val state by loginViewModel.loginState.collectAsStateWithLifecycle()
LoginScreen(
navController = navController,
state = state,
onAction = { loginAction ->
loginViewModel.onAction(loginAction)
}
)
}
on the composable:
@Composable
fun LoginScreen(
navController: NavController,
modifier: Modifier = Modifier,
state: LoginState,
onAction: (LoginAction) -> Unit
){
}
With this approach, I am able to preview my LoginScreen composable. This however means I need to use actions for all possible UI actions, and pass my state as well. I don't mind this.
Now I am not sure according to best practices, which of these two would be the best approach? Could there be another recommended approach? Any pointers?
Share asked Nov 22, 2024 at 7:31 muoki_Dmuoki_D 4091 gold badge11 silver badges27 bronze badges1 Answer
Reset to default 3Please have a look at the Previews in ViewModels chapter in the official documentation:
When you try to preview a composable with
ViewModel
, Android Studio shows an error when rendering the particular composable.
If you want to preview a composable that uses a
ViewModel
, you should create another composable with the parameters fromViewModel
passed as arguments of the composable. This way, you don't need to preview the composable that uses the ViewModel.
We can conclude from the documentation that
- Option 2 is preferred (and also commonly used in Jetpack Compose projects)
- Option 1.1 requires you to pass a manually constructed or mocked ViewModel instance to the Composable, which is some additional effort
- Option 1.2 should not be used as it breaks any Preview
Also check out this stackoverflow question which also recommends following approach 2 by lifting the ViewModel to the parent Composable.
本文标签:
版权声明:本文标题:android - How to instantiate viewModel for a screen composable and still be able to preview the composable - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742291837a2447947.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论