View Model Creation in Jetpack Compose

2 ways (by viewModels and viewModel() composable function) to create view model in your Jetpack compose app

ยท

2 min read

View Model Creation in Jetpack Compose

In Jetpack Compose, you can use either by viewModels or viewModel() composable function to create view model.

by viewModels

class MainActivity : ComponentActivity() {

   private val viewModel by viewModels<MainViewModel>()

   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)

       setContent {
           MainScreen(viewModel)
       }
   }
}

can be just replaced with

viewModel() composable

class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            MainScreen(viewModel())
        }
    }
}

Source code example (Simple Rest API Demo App): MainActivity.kt.

If that doesn't work, you want to explicity include this library in your build.gradle file.

implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.4.0'

by ViewModels (custom constructor)

For view model creation that has custom constructor, by viewModels code looks like this:

private val viewModel by viewModels<MainViewModel> {
    MainViewModelFactory(repository)
}

viewModel() composable (custom constructor)

To convert it to viewModel() composable function, it looks like this

viewModel(factory = MainViewModelFactory(repository))

You pass in the custom view model factory (i.e. MainViewModelFactory) as parameter of viewModel() composable function.

Note: viewModel() is a composable function, you need to call it within a composable function.

Source code example (Android News app): MainActivity.kt.

HiltViewModel() - DI Framework

Another way to create view model is to use Hilt dependency injection(DI) framework. It is very similar to viewModel() composable function. You just replace it with hiltViewModel() which is also a composable function.

@AndroidEntryPoint
class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MainScreen(
                viewModel = hiltViewModel(), 
                useSystemUIController = true
            )
        }
    }
}

Source code example (Android News app - Hilt branch): MainActivity.kt.

For how to use the Hilt dependency injection, refer to this article:

Conclusion

I wasn't aware of this viewModel() composable function. So I had been using by viewModel. I think it is better to use viewModel() composable function if your app is Jetpack Compose. You can also call viewModel() many times and only one instance of view model is created.

One thing to keep in mind when using viewModel() composable function is the view model lifecycle is scoped to composable function that is still in the back stack. If the composable function is removed from the back state, the view model is destroyed. For details, refer to this article.

Did you find this article valuable?

Support Vincent Tsen - AndroidDev Blog by becoming a sponsor. Any amount is appreciated!

ย