Я новичок в разработке Android, и я застрял в поисках способа сделать этот шаблон, используя некоторые библиотеки Android, такие как Dagger2, Fragments и ViewModel.
Я надеюсь, что некоторые из вас помогут мне с этим или расскажут, как это обычно делается на Android.
Я ищу что-то вроде этого:
class FragmentPager: Fragment() {
@Inject
@Named("FullListFragment")
lateinit var listFragment: ListFragment
@Inject
@Named("FilteredListFragment")
lateinit var filteredListFragment: ListFragment
//Use fragments in the viewPager.
}
Что я пытаюсь сделать:
У меня есть фрагмент, который показывает список элементов. Он также имеет ViewModel, отвечающий, помимо прочего, за обновление списка. ViewModel получает список из репозитория, который запрашивает базу данных. Пока все довольно просто.
Мой вариант использования состоит в том, что мое приложение показывает список элементов во множестве разных областей внутри приложения, но с разными данными. Например, полный список, отфильтрованный список ...
Моя идея заключалась в том, чтобы создать репозиторий как интерфейс с одним методом: fun getItems(): List<Item>
и разными экземплярами для каждого источника данных. В результате у меня:
- ListFragment (класс, наследующий от Fragment)
- ListViewModel (класс, наследующий от ViewModel)
- ListRepository (интерфейс)
- FullListRepository (класс, реализующий ListRepository) - ›Получает все элементы из БД
- FilterListRepository (класс, реализующий ListRepository) - ›Получает элементы фильтра из БД.
- JoinedListRepository (класс, реализующий ListRepository) - ›Получает элементы из БД, но путем объединения разных таблиц
Эти элементы будут работать вместе в таком идеальном мире:
fun buildListFragment(repository: ListRepository) {
val viewModel = ListViewModel(repository)
val fragment = ListFragment(viewModel)
return fragment
}
val fullListFragment = buildListFragment(FullListRepository())
val filteredListFragment = buildListFragment(FilterListRepository())
val joinedListFragment = buildListFragment(JoinedListRepository())
Как я могу сделать что-то подобное с помощью Dagger2 для внедрения зависимостей, ViewModelFactory для создания ViewModels и фрагментов.
Ограничения, с которыми я сталкиваюсь:
- Моя ViewModel имеет параметры, поэтому может быть создана только через ViewModelFactory.
- ViewModel не может быть введен конструктором во фрагмент и должен быть создан внутри с помощью viewModelFactory в onCreate. На данный момент невозможно указать Dagger2, какую реализацию ListRepository следует использовать для создания ViewModelFactory.
class ListFragment: Fragment() {
@Inject
lateinit var viewModelFactory: ViewModelProvider.Factory
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
viewModel = ViewModelProvider(this, viewModelFactory).get(CardListViewModel::class.java)
}
}
- Я знаю, что вы можете использовать аннотацию @Named для запроса внедрения различных реализаций репозитория, но когда фабрика создается внутри тела фрагмента, уже слишком поздно запрашивать репозиторий @Named, потому что вы знаете, какой репозиторий вам нужен, прежде чем создавать фрагмент не после.
Вопросов:
- Возможно ли это решение с использованием Dagger2 и ViewModels?
- Как я могу этого добиться? Есть какой-нибудь совет?
- Используете ли вы обычно другой шаблон, который подходит к тому же варианту использования?