Como usar SavedStateHandle e navegação Safe Args

Sep 05 2020

Eu tenho duas opções para passar dados entre o fragmento, os argumentos seguros de navegação e SavedStateHandle do viewModel, qual é a diferença entre eles e como usá-los no lugar correto?

Respostas

3 akelix Sep 07 2020 at 22:56

Existem poucas discussões sobre este assunto. android ViewModelFactory com punho https://issuetracker.google.com/issues/136967621

Para mim, a solução mais óbvia é usar algo como

SafeArgs.fromSavedStateHandle(savedStateHandle)

Mas, por enquanto, estou usando chaves de string.

2 AleksandrBelkin Nov 13 2020 at 08:06

Se você estiver usando hilt, você pode envolver os argumentos de entrada no fragmento (e outros componentes) assim

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 então para o modelo de visualização, você pode herdar de algo assim

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 então use-o da mesma forma que usaria argumentos seguros

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

    private val args: FooFragmentArgs by navArgs()
}