Jetpack Compose Navigation with ViewModel
I want to implement an architecture in my Jetpack Compose Application. Also, do navigations because I have several pages in my app.
Use ViewModel and Navigation separate. How?
- Import ViewModel & Navigation Libraries.
⚠️ Caution: be sure to import
2. Create a Navigation Composable function and pass your
navHostController which, is accessed by
3. Create your viewModel Classes separate as you did before and continue your development.
❌ Soon, you will notice that this approach won’t work in a more scaled application, and you need to implement a better architecture. ❌
So you may wonder how I can handle my navigations in My
ViewModel classes and don’t pass both
navController to each compose function.
If you are familiar with
ViewModel previous, you would know that it is a singleton class that is created with the following snippet:
So to pass a variable to a
ViewModel class, we need to create the
ViewModelFactory class and pass it to the
ViewModel like the following:
Last but not least we extract navigations as functions and pass them with ViewModel like so:
💡 Extra Point: How to pass down navigation functions with arguments?
The secret is passing lambdas instead of functions and passing the parameter in the desired location in your code
Ok, let’s implement this using Dependency Injection.
Hilt for DI. The benefit of using DI is that there is no need for ViewModelFactory classes anymore. This helps us have a much cleaner code.
To implement, we use
@HiltViewModel and inject the
Navigator class in the constructor of our
Navigator Class is the following object responsible to provide our navHostController (Notice:
navHostController is wrapped in this class because we want to inject it in our
⚠️ Caution: there is a flaw here: the memory leak caused by the
navController initialization method. I’ll be glad if you could provide a better architecture in the comments. Also, be aware of handling this leak manually.
Finally, there is no need to create a
ViewModel instance in the
Navigation class; you get your
viewModel by passing
hiltViewModel() as the param of your View.
Note that you should add the following dependency of
Hilt in your app’s
Now you can concentrate on your creativity instead of thinking about the architecture.
The solution to memory leak and another approach that is better than mine can be found here:
Don’t forget to clap and share if you enjoyed this article. Also, I am really looking forward to seeing your opinions in the comments.