Same fragment with different navgraph by hiltNavGraphViewModels

Viewed 113

I followed single activity pattern for my app. My MainActivity has a bottom navigation with 4 fragments.

main nav graph

nav_home and nav_video have same fragment so I want to HomeViewModel and VideoViewModel keep their states within these graphs. As you can see below.

nav_home.xml

nav home graph

nav_video.xml

nav video graph

On my fragment I use hiltNavGraphViewModels extension to keep viewmodel states.

@AndroidEntryPoint
class CourseDetailFragment : Fragment(R.layout.fragment_course_detail),
    LoadingDelegate by LoadingDelegateImpl(), NavigationDelegate by NavigationDelegateImpl() {

    private val binding by viewBinding(FragmentCourseDetailBinding::bind)
    private val viewModel: CourseDetailViewModel by viewModels()
    private val categoryViewModel: CategoryViewModel by hiltNavGraphViewModels(R.id.nav_video)
    private val homeViewModel: HomeViewModel by hiltNavGraphViewModels(R.id.nav_home)

If I reach this fragment from home, categoryViewModel throws exception and it says:

java.lang.IllegalArgumentException: No destination with ID 2131362218 is on the NavController's back stack. The current destination is Destination(com.example.app:id/courseDetailFragment) label=CourseDetailFragment class=com.example.app.ui.course.CourseDetailFragment

logcat exception

On the other hand, if I reach this fragment from video, homeViewModel throws same exception.

Any help would be most welcomed. Thanks.

1 Answers

Maybe you can use this:

private val sampleViewModel: SampleViewModel by hiltNavGraphViewModels(findNavController().graph.id)

However in my case, the vm is lazy initialized even before onCreate() and findNavController() is not yet available at that time.

Here's what I did:

fun provideVM(): SampleVM =
hiltNavGraphViewModels<SampleVM>(findNavController().graph.id).value

provideVM() is called during onViewCreated()

Related