I have two options to pass data between fragment, the navigation's safe args and viewModel's SavedStateHandle, what's the difference between them and how to use them in the correct place?
I have two options to pass data between fragment, the navigation's safe args and viewModel's SavedStateHandle, what's the difference between them and how to use them in the correct place?
There are few discussions about this issue. android ViewModelFactory with hilt https://issuetracker.google.com/issues/136967621
For me, most obvious solution is to use something like
SafeArgs.fromSavedStateHandle(savedStateHandle)
But for now, I am using string keys.
If you are using hilt you can wrap the incoming arguments in the fragment (and other components) like so
open class BaseFragment : Fragment() { // Inherit your fragment from this
override fun setArguments(args: Bundle?) {
if (args != null) {
if (args.getBundle(BUNDLE_ARGS) != null) {
super.setArguments(args)
} else {
super.setArguments(Bundle(args).apply {
putBundle(BUNDLE_ARGS, args) // Wrap the arguments as BUNDLE_ARGS
})
}
} else {
super.setArguments(null)
}
}
}
and then for the view model, you can inherit from something like that
open class ArgsViewModel(private val savedStateHandle: SavedStateHandle) : ViewModel() {
val arguments get() = savedStateHandle.get<Bundle>(BUNDLE_ARGS)
@MainThread
inline fun <reified Args : NavArgs> navArgs() = NavArgsLazy(Args::class) {
arguments ?: throw IllegalStateException("ViewModel $this has null arguments")
}
}
And then use it just like you would use safe args
class FooViewModel @ViewModelInject constructor(
@Assisted savedStateHandle: SavedStateHandle
) : ArgsViewModel(savedStateHandle) {
private val args: FooFragmentArgs by navArgs()
}