我正在开发基于架构组件(ViewModel / Room / Livedata)和RecyclerView的清单应用程序。该应用基于Google在开发人员培训手册中推荐的做法。
Advanced Android Development Course - Working with Architecture Components: Room, LiveData, ViewModel
该应用程序具有非常复杂的数据模型,可实现为Room实体和关系(10多个表,外键等)。我也有相应的DAO。
主要活动是要处理的项目列表的RecyclerView,当用户单击某个项目时,将打开一个特殊的SubActivity,并且用户必须输入与项目相关的数据,并将其保存到Room中。随着用户返回MainActivity,LiveData刷新了数据。借助ViewModel,配置更改也可以工作。
应用程序的工作流程如下:
我想要的是过滤MainActivity的RecyclerView上的项目列表。
Google和Stackowerflow帖子建议使用Livedata的切换图进行过滤。
Best practice: Runtime filters with Room and LiveData
Android Room LiveData select query parameters
我不喜欢这种方法,因为
房间无法基于复杂的过滤器模型提供全面的查询
public abstract class DAO {
@Transaction
@Query("select * " +
"from table1 t1 " +
"join table2 t2 on t2.field = t1.field " +
"join table3 t3 on t3.field = t2.field " +
...
"join tablen tn on tn.field = t(n-1).field " +
"where t1.filterField = filterData.filterField1 " +
and t2.filterField = filterData.filterField2 " +
...
and tm.filterField = filterData.filterFieldm")
public abstract LiveData<List<ComplexData>> getFilteredComplexData(FilterData filterData);
}
其中FilterData
是POJO。
我不得不写
@Transaction
@Query("select * ...")
public abstract LiveData<List<ComplexData>> getFilteredComplexData(filterField1, filterField2, ...);
我的计划如下
FilterActivity完成时
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == INTENT_REQUEST_FILTER) {
if (resultCode == RESULT_OK) {
FilterData filterData = (FilterData)data.getParcelableExtra(INTENT_MESSAGE_FILTER_DATA));
RecyclerviewAdapter.setComplexData(ViewModel.getComplexData().getValue(), filterData);
}
}
}
在RecyclerView的适配器中
void setComplexData(List<ComplexData> complexData, FilterData filterData) {
if (filterData != null) {
List<ComplexData> = complexData.
stream().
filter(do filterData.filter1 here).
filter(do filterData.filter2 here).
...
filter(do filterData.filterm here).
collect(Collectors.toList());
}
else {
List<ComplexData> = complexData;
}
notifyDataSetChanged();
}
因此,将所有数据保留在LiveData中,并在用户进行过滤时,使用过滤后的列表填充RecyclerView的适配器并通知更改。
以这种方式过滤是否正确?有陷阱吗?