I wanted ViewModel to store bundle of data to save state of Fragment's View since ViewModel is independent of Fragment and its View, but shouldn't save the state as deeply as onSaveInstanceState(outBundle: Bundle) does (save state of EditTexts etc when you navigate throught the app, but no need to handle process death). So I created nullable Bundle property in ViewModel that should do the job (when onDestroyView() is invoked Bundle of data is passed to ViewModel, then in onCreateView(...) I'm reading it, and if it's null then you're in this destination for the first time), but it kept being null.
With the help of Debugging and Logs i figured out that when you navigate throught the app with use of BottomNavigationView and NavigationComponent, Hilt creates new Instance of Fragment, new instance of ViewModel, and then the fragment that should be restored from backstack is being destroyed.
Here are logs that prove it (navigate to another destination and navigate back)
2020-11-24 12:14:31.770 I: Fragment hash code - 160176487: onCreate
2020-11-24 12:14:31.844 I: Fragment hash code - 160176487: VM hash code - 167331582
2020-11-24 12:14:36.264 I: Fragment hash code - 184547386: onCreate
2020-11-24 12:14:36.265 I: Fragment hash code - 184547386: VM hash code - 182438472
2020-11-24 12:14:36.385 I: Fragment hash code - 160176487: onDestroy
It happens only with navigation by BottomNavigationView. When I navigate with findNavController().navigate(...) fragments are restored properly, even adapter position of RecyclerView is being restored.
Shouldn't NavigationComponent restore Fragment from the backstack, and shouldn't ViewModel be independent of Fragment and live throught navigation? And why Hilt creates new instances of ViewModels when they should live throught whole app lifecycle since I didn't scope them to any component or module? Or there is a way to be sure ViewModel is independent?
ViewModel:
class ExploreFragmentViewModel @ViewModelInject constructor(...) : ViewModel()
Fragment:
@AndroidEntryPoint
class ExploreFragment : Fragment() {
...
private val viewModel: ExploreFragmentViewModel by viewModels()
...
}
How i setup BottomNavigationView with NavigationComponent in single Activity pattern:
val navController = findNavController(R.id.fragment)
binding.bottomNavBar.setupWithNavController(navController)