Я в некотором роде новичок в разработке 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 (interface)
- 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 для создания ViewModel и фрагментов.
Ограничения, с которыми я сталкиваюсь:
- Мой ViewModel имеет параметры, поэтому их можно создавать только через ViewModelFactory.
- ViewModel не может быть введен конструктором в Fragment и должен быть создан внутри с использованием viewModelFactory i. и создать. На данный момент невозможно сказать 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?
- Как этого добиться? Любой совет?
- Вы обычно используете другой шаблон, который может вписаться в тот же вариант использования?