android - nada - ¿Cómo borrar el valor almacenado de LiveData?
como liberar espacio en mi celular sin borrar nada (5)
Según la documentación de LiveData :
La clase LiveData proporciona las siguientes ventajas:
...
Siempre datos actualizados: si un Ciclo de vida comienza de nuevo (como una actividad que se remonta al estado iniciado desde la pila trasera), recibe los datos de ubicación más recientes (si es que no lo hizo ya).
Pero a veces no necesito esta característica.
Por ejemplo, he seguido LiveData en ViewModel y Observer en Activity:
//LiveData
val showDialogLiveData = MutableLiveData<String>()
//Activity
viewModel.showMessageLiveData.observe(this, android.arch.lifecycle.Observer { message ->
AlertDialog.Builder(this)
.setMessage(message)
.setPositiveButton("OK") { _, _ -> }
.show()
})
Ahora después de cada rotación aparecerá el diálogo anterior.
¿Hay una manera de borrar el valor almacenado después de que se maneje o es un uso incorrecto de LiveData?
En mi caso, SingleLiveEvent no ayuda. Yo uso este código:
private MutableLiveData<Boolean> someLiveData;
private final Observer<Boolean> someObserver = new Observer<Boolean>() {
@Override
public void onChanged(@Nullable Boolean aBoolean) {
if (aBoolean != null) {
// doing work
...
// reset LiveData value
someLiveData.postValue(null);
}
}
};
La respuesta de Alex en los comentarios es que creo exactamente lo que estás buscando. Hay código de ejemplo para una clase llamada SingleLiveEvent . El propósito de esta clase se describe como:
Un observable consciente del ciclo de vida que envía solo nuevas actualizaciones después de la suscripción, que se utiliza para eventos como los mensajes de navegación y Snackbar.
Esto evita un problema común con los eventos: en el cambio de configuración (como la rotación) se puede emitir una actualización si el observador está activo. Este LiveData solo llama al observable si hay una llamada explícita a setValue () o call ().
Necesitas usar SingleLiveEvent para este caso
class SingleLiveEvent<T> : MutableLiveData<T>() {
private val pending = AtomicBoolean(false)
@MainThread
override fun observe(owner: LifecycleOwner, observer: Observer<T>) {
if (hasActiveObservers()) {
Log.w(TAG, "Multiple observers registered but only one will be notified of changes.")
}
// Observe the internal MutableLiveData
super.observe(owner, Observer<T> { t ->
if (pending.compareAndSet(true, false)) {
observer.onChanged(t)
}
})
}
@MainThread
override fun setValue(t: T?) {
pending.set(true)
super.setValue(t)
}
/**
* Used for cases where T is Void, to make calls cleaner.
*/
@MainThread
fun call() {
value = null
}
companion object {
private const val TAG = "SingleLiveEvent"
}
}
Y dentro de ti, la clase viewmodel crea un objeto como:
val snackbarMessage = SingleLiveEvent<Int>()
No estoy seguro de si funcionará en su caso, pero en mi caso (aumentar / disminuir la cantidad de artículos en la sala haciendo clic en las vistas) eliminando el Observador y comprobando si hay observadores activos, permítame hacer el trabajo:
LiveData<MenuItem> menuitem = mViewModel.getMenuItemById(menuid);
menuitem.observe(this, (MenuItem menuItemRoom) ->{
menuitem.removeObservers(this);
if(menuitem.hasObservers())return;
// Do your single job here
});
});
Si necesitas una solución simple, prueba esta:
class SingleLiveData<T> : MutableLiveData<T?>() {
override fun observe(owner: LifecycleOwner, observer: Observer<in T?>) {
super.observe(owner, Observer { t ->
if (t != null) {
observer.onChanged(t)
postValue(null)
}
})
}
}
Úsalo como un MutableLiveData regular