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?
Navigation is a framework for navigating between 'destinations' within an Android application that provides a consistent API whether destinations are implemented as Fragments, Activities, or other components. Latest Update. Stable Release. Release Candidate. Beta Release.
Use Safe Args to pass data with type safety. The Navigation component has a Gradle plugin called Safe Args that generates simple object and builder classes for type-safe navigation and access to any associated arguments. Safe Args is strongly recommended for navigating and passing data, because it ensures type-safety.
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()
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With