Как очистить сохраненное значение LiveData?
по данным документация LiveData:
класс LiveData предоставляет следующие преимущества:
...
всегда в курсе данных: если жизненный цикл начинается снова (например, действие возвращается в начальное состояние из заднего стека), он получает последние данные о местоположении (если это еще не произошло).
но иногда мне не нужна эта функция.
например, у меня после LiveData в ViewModel и наблюдатель в деятельности:
//LiveData
val showDialogLiveData = MutableLiveData<String>()
//Activity
viewModel.showMessageLiveData.observe(this, android.arch.lifecycle.Observer { message ->
AlertDialog.Builder(this)
.setMessage(message)
.setPositiveButton("OK") { _, _ -> }
.show()
})
теперь после каждого поворота появится старый диалог.
есть ли способ очистить сохраненное значение после его обработки или это неправильное использование LiveData вообще?
4 ответов
ответ Алекса в комментариях-я думаю, что именно то, что вы ищете. Существует пример кода для класса SingleLiveEvent. Назначение этого класса описывается следующим образом:
наблюдаемый жизненный цикл, который отправляет только новые обновления после подписка, используемая для таких событий, как навигация и сообщения Snackbar.
Это позволяет избежать общей проблемы с событиями: при изменении конфигурации (как вращение) обновление может быть выдано, если наблюдатель активен. Это LiveData вызывает только наблюдаемое, если есть явный вызов setValue () или call ().
в моем случае SingleLiveEvent не помогает. Я использую этот код:
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);
}
}
};
Я не уверен, будет ли это работать в вашем случае, но в моем случае (увеличение/уменьшение количества элементов в комнате, нажав на просмотры) удаление наблюдателя и проверка, есть ли активные наблюдатели, позвольте мне выполнить эту работу:
LiveData<MenuItem> menuitem = mViewModel.getMenuItemById(menuid);
menuitem.observe(this, (MenuItem menuItemRoom) ->{
menuitem.removeObservers(this);
if(menuitem.hasObservers())return;
// Do your single job here
});
});
вам нужно использовать SingleLiveEvent для этого случая
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"
}
}
и внутри вас класс viewmodel создает объект типа:
val snackbarMessage = SingleLiveEvent<Int>()