如何在使用 Room 和 LiveData 执行新的 get 方法后刷新 UI?

How to refresh UI after performing new get method using Room and LiveData?

我正在使用 JetPack 架构编写 android 应用程序(我也在使用 Sunflower 应用程序作为灵感)。

我有回收站视图和任务列表。为了得到它们,我在视图模型中使用了以下函数。并且初始加载工作正常。

但是我也有日期选择器,我想在其中将 finishedDate 更新为新日期以获取前一天完成的任务。

更新 finishedDate 变量或调用另一个 getTasksByFinishedDate 函数来重新分配任务(在将范围从 val 更改为 var 之后)没有任何效果。我仍然只显示初始任务。

此字段 (LiveData) 的观察功能正常工作,因为如果我添加具有当前显示的完成日期的新任务,我将在 UI.

上看到它

我无法在初次通话后将它们过滤到不同的日期。

代码如下:

视图模型:

fun updateDate(year: Int, month: Int, day: Int) {
    finishedDate.set(Calendar.YEAR, year)
    finishedDate.set(Calendar.MONTH, month)
    finishedDate.set(Calendar.DAY_OF_MONTH, day) 
    // tasks: LiveData<List<Task>> = taskRepository.getTasksByFinishedDate(finishedDate)
    }

val tasks: LiveData<List<Task>> = taskRepository.getTasksByFinishedDate(finishedDate)

道​​:

@Query("SELECT * FROM task WHERE finishedDate = :finishedDate")
fun getTasksByFinishedDate(finishedDate: Calendar): LiveData<List<Task>>

片段订阅UI:

ViewModel.tasks.observe(viewLifecycleOwner) { result ->
   adapter.submitList(result)
}

日期选择器:

    private val model: NewTaskViewModel by activityViewModels()
    override fun onDateSet(view: DatePicker, year: Int, month: Int, day: Int) {
        this.year = year
        this.month = month
        this.day = day

        model.updateDate(year, month, day)
    }

您的问题的解决方案称为MediatorLiveData

想法是,您可以在 ViewModel 中保留一个最终的 LiveData 对象,并且只调整 Mediator 的 source

在你的回购中:

private MediatorLiveData<List<Tasks>> mObservableTasks;
private LiveData<List<SeedEntity>> tasks;

private DataRepository(...) {
    ...
    tasks = mDatabase.myDao().getTasksByFinishedDate(defaultDate);
    mObservableTasks = new MediatorLiveData<>();
    mObservableTasks.addSource(tasks,
            taskLists-> {
                if (mDatabase.getDatabaseCreated().getValue() != null) {
                    mObservableTasks.postValue(taskLists);
                }
            });
}

public void updateDate(Calendar finishedDate)
{
        mObservableTasks.removeSource(tasks);
        tasks = mDatabase.myDao().getTasksByFinishedDate(finishedDate);
        mObservableTasks.addSource(tasks,
                taskLists-> {
                    if (mDatabase.getDatabaseCreated().getValue() != null)
                        mObservableTasks.postValue(taskLists);
                });

public LiveData<List<Tasks>> getObservableTasks(){
    return mObservableTasks;
}

在您的 ViewModel 中:

final LiveData<..> mObservableTasks = repo.getObservableTasks();
public LiveData<..> getObservableTasks(){
    return mObservableTasks;
}

在您看来:

ViewModel.mObservableTasks.observe(viewLifecycleOwner) { result ->
    adapter.submitList(result)
}

希望这能说明问题;)