Comment utiliser SavedStateHandle et la navigation Safe Args

Sep 05 2020

J'ai deux options pour passer des données entre fragment, les arguments sûrs de la navigation et SavedStateHandle de viewModel, quelle est la différence entre eux et comment les utiliser au bon endroit?

Réponses

3 akelix Sep 07 2020 at 22:56

Il y a peu de discussions sur ce problème. android ViewModelFactory avec poignée https://issuetracker.google.com/issues/136967621

Pour moi, la solution la plus évidente est d'utiliser quelque chose comme

SafeArgs.fromSavedStateHandle(savedStateHandle)

Mais pour l'instant, j'utilise des clés de chaîne.

2 AleksandrBelkin Nov 13 2020 at 08:06

Si vous utilisez Hilt, vous pouvez envelopper les arguments entrants dans le fragment (et d'autres composants) comme ceci

open class BaseFragment : Fragment() { // Inherit your fragment from this

    override fun setArguments(args: Bundle?) {
        if (args != null) {
            super.setArguments(Bundle(args).apply {
                putBundle(BUNDLE_ARGS, args) // Wrap the arguments as BUNDLE_ARGS
            })
        } else {
            super.setArguments(null)
        }
    }
}

puis pour le modèle de vue, vous pouvez hériter de quelque chose comme ça

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")
    }
}

Et puis utilisez-le comme vous utiliseriez des arguments sûrs

class FooViewModel @ViewModelInject constructor(
    @Assisted savedStateHandle: SavedStateHandle
) : ArgsViewModel(savedStateHandle) {

    private val args: FooFragmentArgs by navArgs()
}