Come utilizzare SavedStateHandle e navigazione Safe Args

Sep 05 2020

Ho due opzioni per passare i dati tra il frammento, gli argomenti sicuri di navigazione e il SavedStateHandle di viewModel, qual è la differenza tra loro e come usarli nel posto corretto?

Risposte

3 akelix Sep 07 2020 at 22:56

Ci sono poche discussioni su questo problema. Android ViewModelFactory con elsa https://issuetracker.google.com/issues/136967621

Per me, la soluzione più ovvia è usare qualcosa di simile

SafeArgs.fromSavedStateHandle(savedStateHandle)

Ma per ora, sto usando le chiavi di stringa.

2 AleksandrBelkin Nov 13 2020 at 08:06

Se stai usando l'elsa puoi racchiudere gli argomenti in arrivo nel frammento (e in altri componenti) in questo modo

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

e poi per il modello di visualizzazione, puoi ereditare da qualcosa di simile

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

E poi usalo proprio come useresti gli argomenti sicuri

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

    private val args: FooFragmentArgs by navArgs()
}