android-fragmentsandroid-architecture-componentsandroid-livedataandroid-mvvmandroid-architecture-lifecycle

Should I share my ViewModel across two fragments?


I'm attempting to follow Android best practices and use the latest recommended architecture components. You can see my attempt so far here: https://github.com/randroid88/TodayILearned

Right now the app's features are very limited.

The problem is that only HomeFragment has access to EntryViewModel right now.

So in my current design, I pass the new entry text from EntryEditorFragment to HomeFragment via an argument bundle (using SafeArgs from the new Navigation Architecture Component), then HomeFragment creates the new entry via the EntryViewModel:

val safeArgs = HomeFragmentArgs.fromBundle(arguments!!)
    savePossibleNewEntry(safeArgs.entryText)

private fun savePossibleNewEntry(entryText: String) {
    entryViewModel!!.insert(EntryCreator().create(entryText))
}

This doesn't feel right.

Would it be better if EntryViewModel also had access to EntryEditorFragment?

In order to accomplish this, would I have to scope the ViewModel to the Activity as explained here on this blog?

What is the best practice here?


Solution

  • The Android documentation suggested sharing a ViewModel for "a common case of master-detail fragments" so I decided to do the same for my case.

    As suggested, I scoped the ViewModel to the Activity in both fragments:

    entryViewModel = activity?.run {
            ViewModelProviders.of(this, EntryViewModelFactory(this.application, EntryRepository(this.application))).get(EntryViewModel::class.java)
        } ?: throw Exception("Invalid Activity")
    

    Here's the commit where I made the change: https://github.com/randroid88/TodayILearned/commit/e307bd3f238e68a399a2a1619438770d908a606d