Я работаю над приложением инвентаризации на основе компонентов архитектуры (ViewModel/Room/Livedata) и RecyclerView. Приложение основано на практике, рекомендованной Google в учебном пособии для разработчиков.
Курс продвинутой разработки для Android - Работа с архитектурными компонентами: Room, LiveData, ViewModel
Приложение имеет довольно сложную модель данных, которая реализована в виде сущностей и отношений Room (более 10 таблиц, внешних ключей и т. д.). У меня тоже есть соответствующие DAO.
Основное действие — это RecyclerView списка элементов для работы, и когда пользователь нажимает на один из элементов, открывается специальное вспомогательное действие, и пользователь должен ввести данные, связанные с элементом, которые сохраняются в комнате. Когда пользователь возвращается к MainActivity, данные обновляются благодаря LiveData. Также изменения конфигурации работают благодаря ViewModel.
Рабочий процесс приложения следующий:
- Пользователь загружает данные с сервера, создается БД комнаты, и MainActivity показывает список элементов для работы.
- Пользователь просматривает элементы, нажимает на один из них, открывается подактивность для конкретного элемента, где пользователь записывает свои данные, которые сохраняются в комнате.
- Когда все элементы завершены, пользователь загружает записанные данные элемента на сервер, данные в комнате удаляются, пользователь может загрузить новый список элементов.
- Пользователь не может удалить или вставить новый элемент, он может только записать его данные в соответствующую SubActivity. Элементы удаляются/вставляются при загрузке данных.
Я хочу отфильтровать список элементов в RecyclerView MainActivity.
Сообщения Google и Stackowerflow рекомендуют схему переключения Livedata для фильтрации.
Рекомендации: Фильтры среды выполнения с помощью Room и LiveData
Android Room LiveData выбирают параметры запроса< /а>
Мне не нравится этот подход, потому что
- Мне нужно пойти в комнату и запросить данные в новой AsyncTask
Комната не предоставляет исчерпывающий запрос на основе сложной модели фильтра
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, ...);
Мой план следующий
- Пользователь указывает FilterData в FilterActivity
Когда 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 отфильтрованным списком и уведомляют об изменениях.
Правильно ли фильтровать таким образом? Есть ли в нем какой-нибудь подводный камень?