如何清除LiveData存储值?

Kam*_*358 36 android android-livedata android-architecture-components

根据LiveData文档:

LiveData类具有以下优点:

...

始终是最新数据:如果生命周期再次启动(如从后端堆栈返回到启动状态的活动),它将收到最新的位置数据(如果尚未生成).

但有时候我不需要这个功能.

例如,我在ViewModel中跟随LiveData,在Activity中跟踪Observer:

//LiveData
val showDialogLiveData = MutableLiveData<String>()

//Activity
viewModel.showMessageLiveData.observe(this, android.arch.lifecycle.Observer { message ->
        AlertDialog.Builder(this)
                .setMessage(message)
                .setPositiveButton("OK") { _, _ -> }
                .show()
    })
Run Code Online (Sandbox Code Playgroud)

现在每次旋转后都会出现旧的对话框.

有没有办法在处理后清除存储的值或者根本没有使用LiveData?

Lyl*_*yla 39

亚历克斯在评论中的回答是我认为你正在寻找什么.有一个名为SingleLiveEvent的类的示例代码.本课程的目的描述如下:

生命周期感知的observable,仅在订阅后发送新的更新,用于导航和Snackbar消息等事件.

这避免了事件的常见问题:在配置更改(如旋转)时,如果观察者处于活动状态,则可以发出更新.如果显式调用setValue()或call(),则此LiveData仅调用observable.

  • 这不适用于转换. (3认同)

小智 9

如果您需要简单的解决方案,请尝试以下一个:

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)
            }
        })
    }
}
Run Code Online (Sandbox Code Playgroud)

像常规 MutableLiveData 一样使用它


Jur*_*lja 8

我不确定它是否适用于您的情况,但在我的情况下(通过单击视图增加/减少 Room 中的项目数量)删除观察者并检查是否有活跃的观察者让我完成这项工作:

LiveData<MenuItem> menuitem = mViewModel.getMenuItemById(menuid);
menuitem.observe(this, (MenuItem menuItemRoom) ->{
                menuitem.removeObservers(this);
                if(menuitem.hasObservers())return;

                // Do your single job here

                });
});  
Run Code Online (Sandbox Code Playgroud)

2019 年 3 月 20 日更新:

现在我更喜欢这个:MutableLiveData 中来自 Google Samples 的 EventWraper 类

/**
 * Used as a wrapper for data that is exposed via a LiveData that represents an event.
 */
public class Event<T> {

    private T mContent;

    private boolean hasBeenHandled = false;


    public Event( T content) {
        if (content == null) {
            throw new IllegalArgumentException("null values in Event are not allowed.");
        }
        mContent = content;
    }

    @Nullable
    public T getContentIfNotHandled() {
        if (hasBeenHandled) {
            return null;
        } else {
            hasBeenHandled = true;
            return mContent;
        }
    }

    public boolean hasBeenHandled() {
        return hasBeenHandled;
    }
}
Run Code Online (Sandbox Code Playgroud)

在视图模型中:

 /** expose Save LiveData Event */
 public void newSaveEvent() {
    saveEvent.setValue(new Event<>(true));
 }

 private final MutableLiveData<Event<Boolean>> saveEvent = new MutableLiveData<>();

 LiveData<Event<Boolean>> onSaveEvent() {
    return saveEvent;
 }
Run Code Online (Sandbox Code Playgroud)

在活动/片段中

mViewModel
    .onSaveEvent()
    .observe(
        getViewLifecycleOwner(),
        booleanEvent -> {
          if (booleanEvent != null)
            final Boolean shouldSave = booleanEvent.getContentIfNotHandled();
            if (shouldSave != null && shouldSave) saveData();
          }
        });
Run Code Online (Sandbox Code Playgroud)


小智 5

就我而言,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);
        }
    }
};
Run Code Online (Sandbox Code Playgroud)