Cómo utilizar SavedStateHandle y Navigation Safe Args

Sep 05 2020

Tengo dos opciones para pasar datos entre fragmentos, los argumentos seguros de la navegación y SavedStateHandle de viewModel, ¿cuál es la diferencia entre ellos y cómo usarlos en el lugar correcto?

Respuestas

3 akelix Sep 07 2020 at 22:56

Hay pocas discusiones sobre este tema. Android ViewModelFactory con empuñadura https://issuetracker.google.com/issues/136967621

Para mí, la solución más obvia es usar algo como

SafeArgs.fromSavedStateHandle(savedStateHandle)

Pero por ahora, estoy usando claves de cadena.

2 AleksandrBelkin Nov 13 2020 at 08:06

Si está usando hilt, puede envolver los argumentos entrantes en el fragmento (y otros componentes) así

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

y luego, para el modelo de vista, puede heredar algo así

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

Y luego utilícelo como lo haría con argumentos seguros

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

    private val args: FooFragmentArgs by navArgs()
}