Thread
#compose
    r

    rachael

    1 year ago
    Say you're building a new app with compose that will have lots of screens, and many of the screens will handle a fair number of network interactions and business logic. It seems like the preference in a pure compose app is to not use fragments at all. Does that mean a single activity app where I have a ViewModel for every screen that's tied to that single Activity's lifecycle? Are there any potential downsides to having many long-lived ViewModels?
    Vipulyaara

    Vipulyaara

    1 year ago
    The ViewModels don’t have to be tied to the activity. You can have a viewModel scoped to a composable. For example,
    navigation
    can scope a viewModel to a backStackEntry
    val viewModel = hiltNavGraphViewModel()
    edit: val viewModel = viewModel()
    or viewModel(factory = HiltViewModelFactory(LocalContext.current, navBackStackEntry))
    a

    alorma

    1 year ago
    What if not using hilt?
    i

    Ian Lake

    1 year ago
    Any call to
    viewModel()
    within a
    NavHost
    composable
    will scope it to that individual screen (it doesn't matter what factory you use)
    r

    rachael

    1 year ago
    awesome, thanks!
    g

    Gabriel

    1 year ago
    Would you do something like this then?
    NavHost(navController, startDestination = Screen.LaunchScreen.route) {
            composable(Screen.LoadingScreen.route) { LoadingScreen() }
            composable(Screen.LaunchScreen.route) {
                val playersViewModel by viewModels<PlayersViewModel>()
                LaunchScreen(playersViewModel)
            }
        }
    i

    Ian Lake

    1 year ago
    You'd use
    val playersViewModel = viewModel<PlayersViewModel>()
    in Compose land: https://developer.android.com/jetpack/compose/interop#viewmodel
    g

    Gabriel

    1 year ago
    Thanks @Ian Lake!
    i

    Ian Lake

    1 year ago
    But yes, that would correctly scope the
    PlayersViewModel
    instance to only the
    LaunchScreen
    destination
    FunkyMuse

    FunkyMuse

    1 year ago
    What about the factories for the assisted inject, they all need to be injected into the activity then passed to the composables?
    g

    Gabriel

    1 year ago
    @FunkyMuse I've got this working:
    navController = rememberNavController()
        NavHost(navController, startDestination = Screen.LaunchScreen.route) {
            composable(Screen.LoadingScreen.route) { LoadingScreen() }
            composable(Screen.LaunchScreen.route) {
                val playersViewModel = viewModel<PlayersViewModel>(
                    factory = PlayersViewModelFactory(
                        PlayersRepository()
                    )
                )
                LaunchScreen(playersViewModel)
            }
        }
    Colton Idle

    Colton Idle

    1 year ago
    @rachael
    It seems like the preference in a pure compose app is to not use fragments at all. Does that mean a single activity app where I have a ViewModel for every screen that's tied to that single Activity's lifecycle?
    I believe Ian Lake or Adam Powell have basically said that if you're building a pure compose app, then you can likely declare you're handling all config changes in the AndroidManifest, and then you wouldn't even need an AAC ViewModel since the main benefit of AAC VM is that it simplifies config changes for you.
    i

    Ian Lake

    1 year ago
    The Hilt integration would be the other nice part of Jetpack ViewModels
    FunkyMuse

    FunkyMuse

    1 year ago
    @Gabriel i was talking about using @Assisted The injected factories must be in the activity for now
    g

    Gabriel

    1 year ago
    👍