Skip to content

Instantly share code, notes, and snippets.

@Atwa
Last active September 24, 2023 14:43
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Atwa/9643e85e2b5c0d9b772100d87725bcc3 to your computer and use it in GitHub Desktop.
Save Atwa/9643e85e2b5c0d9b772100d87725bcc3 to your computer and use it in GitHub Desktop.
package com.atwa.navigation
import androidx.annotation.IdRes
import androidx.annotation.MainThread
import androidx.fragment.app.Fragment
import androidx.hilt.navigation.HiltViewModelFactory
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelLazy
import androidx.navigation.fragment.findNavController
/**
* The viewModel must be created in the owner fragment for the first time using hiltNavGraphViewModels as following :
```
private val mViewModel by hiltNavGraphViewModels<SomeViewModel>(R.id.someDestination)
```
The same instance of the viewModel can then be retrieved in any other later fragment using backStackViewModels as following:
```
private val mViewModel by backStackViewModels<SomeViewModel>(R.id.someDestination)
```
Note :
- Destination can be either a nav graph's id or a destination's id for any fragment in any nav graph.
- Destination must be same in both fragments to retrieve the same instance of the cached viewModel.
- In case the destination doesn't exist in the later fragment's back stack then null would be returned.
* **/
@MainThread
public inline fun <reified VM : ViewModel> Fragment.backStackViewModels(
@IdRes destinationId: Int
): Lazy<VM?> = lazy {
findNavController().currentBackStack.value.lastOrNull { it.destination.id == destinationId }
?.let { backStackEntry ->
ViewModelLazy(
VM::class,
{ backStackEntry.viewModelStore },
{ HiltViewModelFactory(requireActivity(), backStackEntry) },
{ defaultViewModelCreationExtras }
).value
} ?: run { null }
}
@Atwa
Copy link
Author

Atwa commented Sep 21, 2023

The viewModel must be created in the owner fragment for the first time using hiltNavGraphViewModels as following :

private val mViewModel by hiltNavGraphViewModels<SomeViewModel>(R.id.someDestination)

The same instance of the viewModel can then be retrieved in any other later fragment using backStackViewModels as following:

private val mViewModel by backStackViewModels<SomeViewModel>(R.id.someDestination)

Note :

  • Destination can be either a nav graph's id or a destination's id for any fragment in any nav graph.
  • Destination must be same in both fragments to retrieve the same instance of the cached viewModel.
  • In case the destination doesn't exist in the later fragment's back stack then null would be returned.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment