The Navigation component recommends a Single Activity Architecture, and the page on Dagger recommends sharing common ViewModels across Fragments using Dagger scopes.
But this requires having a parent Activity from which the Fragments get the Dagger component, as shown in this line from the docs: (activity as LoginActivity).loginComponent.inject(this)
This is kind of pointless when you only have a single Activity across your app as that's basically the same as using the @Singleton
scope for the lifetime of your whole app. It also prevents you from using FragmentScenario for testing your Fragments as they are now tied to your specific Activity.
What's the best way to share a single ViewModel through Dagger, across Fragments, without giving it a @Singleton
scope or tying it to an Activity?
I'm guessing that you're talking about androidx.lifecycle.ViewModel
which manages its own lifecycle and should not have any scope to allow for it to do just that. If you add your own scopes on top it'll just end up with broken and/or confusing behavior.
As such you shouldn't inject those ViewModels directly either but use the ViewModel factories and lookup methods, or—again—you'd end up with broken and/or confusing behavior since the ViewModel would behave differently to what all of its official documentation states. (You may write a bunch of boilerplate to move this process into modules, but ultimately you'd still need to let androidx manage the lifecycle)
If you don't want to use androidx.lifecycle.ViewModel
but want to get the same/similar behavior then you'd have to create your own scope in-between components. That scope should live shorter than the application, but longer than any single Activity instance to allow for those objects to be reused after configuration changes and so on.