首页 > 解决方案 > 使用 Room 和 LiveData 执行新的 get 方法后如何刷新 UI?

问题描述

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

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

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

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

观察功能对该字段 (LiveData<List>) 正常工作,因为如果我添加具有当前显示的完成日期的新任务,我将在 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)
    }

标签: androidkotlinandroid-roomandroid-livedataandroid-jetpack

解决方案


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

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

在您的回购中:

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

在您的视图模型中:

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

在您看来:

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

希望这能说明问题;)


推荐阅读