【问题标题】:How to query live data depending on an argument with Android Room?如何根据 Android Room 的参数查询实时数据?
【发布时间】:2018-12-27 23:42:37
【问题描述】:

我正在开发一个 Android 应用程序,用户可以在其中根据特定日期保存膳食及其金额。 目前,时间在 SQLite 数据库中存储为yyyy-mm-dd 字符串(我稍后可能会更改数据类型)。 用户可以在CalendarView 上选择日期,RecylerView 应该只显示所选日期的饭菜。我不想检索所有行,而只是根据日期查询行。 我正在使用Room Persistence Library

我怎样才能做到这一点?

我正在使用 LiveData<List<MYOBJECT>> 和适当的 Observable Listener:

final MyViewModel myViewModel = ViewModelProviders.of(this).get(MyViewModel.class); 
String myDate = getDateFromCalendarView();    

myViewModel.getMealsOnDate(myDate).observe(this, new Observer<List<MYOBJECT>>() {
        @Override
        public void onChanged(@Nullable List<MYOBJECT> myObjects) {
            adapter.setItems(myObjects); // adapter from RecyclerView
        }
    });

这是我的 DAO 界面中的查询:

@Query("SELECT * FROM meals WHERE meals_date = :date")
LiveData<List<MYOBJECT>> getMealsOnDate(String date);

目前观察者不会对myDate 中的不同值做出反应,因此我无法从我的数据库中查询不同的行。

这是否可能,还是我必须坚持查询整个表,然后从我的List&lt;MYOBJECT 中选择数据?

【问题讨论】:

  • 给我看看你的 DAO

标签: java android android-recyclerview android-room


【解决方案1】:

不要创建 list observable,而是创建 myDate 变量 observable。因为它是更改的日期而不是列表。 您可以通过以下方式实现:

在 viewModel 中将您的 myDate 设为 MutabeLiveData。然后,您可以在使用setValue(newDate)CalenderView 中选择日期时更改其值。

现在,观察此myDate,并在值更改时,获取具有更新日期值的列表并更新RecyclerView

也使用 TimeStamp 而不是将日期存储为 yyyy-mm-dd 字符串。

***********更新*************

进一步说明的示例

ViewModel 类中这样做

MutableLiveData<String>() myDate=new MutableLiveData<String>();

Activity 中这样做:

calendarView.setOnDateChangeListener( new CalendarView.OnDateChangeListener() {
public void onSelectedDayChange(CalendarView view, int year, int month, int dayOfMonth) {
   myViewModel.myDate.setValue(""+year+"-"+month+"-"+dayOfMonth);//This will invoke the observer
}});

myViewModel.myDate.observe(this, new Observer<String>() {
        @Override
        public void onChanged(@Nullable String newDate) {
           //do this on dedicated thread
           List<MYOBJECT> myObjects=myViewModel.getMealsOnDate(newDate)
           adapter.setItems(myObjects); // adapter from RecyclerView
        }
    });

注意: 1.getMealsOnDate()不需要包装成LiveData。 Dao中的方法可以返回List&lt;MYOBJECT&gt;而不是LiveData&lt;List&lt;MYOBJECT&gt;&gt;,所以你不需要观察它。

2.不要在主线程上运行db查询,并调用适配器的setItems()中的notifyDataSetChanged刷新Recyclerview。

【讨论】:

  • 这听起来是个很有前途的想法。不幸的是,我仍然无法想象如何在我的 ViewModel 中实现这一点。能给我举个小例子吗?
  • 谢谢你的好例子!但是,这意味着如果发生更改(例如新条目),则不会更新 RecyclerView。这就是为什么我使用 LiveData 作为膳食列表的原因。我不必担心与观察者一起更新。此外,数据库查询仅在主线程上执行以进行测试。我在异步执行方面遇到了一些问题
【解决方案2】:

hereherehere 已经回答了类似的问题。我相信您会在上面提供的链接中找到可以针对您的用例进行修改的适当示例。

我会这样做: 在视图模型中,我将有一个 mutableLive 数据变量保存 myDate

MutableLiveData<String>() myDate = MutableLiveData<String>();

然后我有一个用于吃饭日期的变量

LiveData<List<MyObject>> mealsOnDate = Transformations.switchMap(myDate, (dateString -> getMealsOnDate(dateString)))

然后你可以像这样观察activity或fragments上的fealsOnDate

viewmodel.mealsOnDate.observe(this, new Observer<List<MyObject>>() {
        @Override
        public void onChanged(List<MyObject> list) {
            adapter.setItems(list)
        }
    });

【讨论】:

    猜你喜欢
    • 2019-02-01
    • 1970-01-01
    • 2021-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-06
    相关资源
    最近更新 更多