如何根据Android Room的参数查询实时数据?

时间:2018-12-27 23:42:37

标签: java android android-recyclerview android-room

我正在使用一个Android应用程序,用户可以根据特定日期保存餐点及其金额。 目前,时间以yyyy-mm-dd字符串的形式存储在SQLite数据库中(稍后我可能会更改数据类型)。 用户可以在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<MYOBJECT中选择数据?

2 个答案:

答案 0 :(得分:1)

使用 myDate 变量observable代替创建列表 observable。因为其更改的日期而不是列表。 您可以通过以下方式实现此目标:

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

现在,观察此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<MYOBJECT>而不是LiveData<List<MYOBJECT>>。因此,您无需观察它。

2。不要在主线程上运行数据库查询,而要在适配器的notifyDataSetChanged中调用setItems()来刷新Recyclerview。

答案 1 :(得分:1)

类似的问题已被hereherehere回答。我相信您会在上面提供的链接中找到适合您的用例的适当示例。

我会这样: 在viewmodel中,我将有一个mutableLive数据变量,保存myDate

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

然后我有一个饭食日期变量

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

然后您可以观察活动或类似片段的饭食ondate

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