Kotlin Dagger 2 Совместное использование ViewModel между Activity и Fragment - PullRequest
0 голосов
/ 10 февраля 2020

Как уже упоминалось в заголовке, у меня проблема с инъекцией Dagger 2. У меня есть одно действие и несколько фрагментов. Я пытаюсь поделиться ViewModel активности с каждым дочерним фрагментом. Я основал свое решение на примере задачи Android Architecture от Google. Я создал ViewModelFactory как

ViewModelFactory

Если вы перейдете по ссылке, вы увидите, что в их решении есть отдельный ViewModel для каждого действия и фрагмента. Они не показывают, как бороться со сценарием ios, как мой. Моя реализация ActivityModule выглядит следующим образом:

 @Module
 abstract class SampleModule {
    @ContributesAndroidInjector(
            modules = [
                ViewModelBuilder::class
            ]
    )
    internal abstract fun sampleActivity(): SampleActivity

    @Binds
    @IntoMap
    @ViewModelKey(SampleViewModel::class)
    abstract fun bindViewModel(viewModel: SampleViewModel): ViewModel
}

Моя активность расширяется DaggerAppCompatActivity и фрагмент DaggerFragment, и как следствие, моя инъекция модели представления выглядит просто как

class SampleActivity : DaggerAppCompatActivity() {

   @Inject
   lateinit var viewModel: SampleViewModel
   ...

Я могу ' не могу найти веб-решение моей проблемы. Я довольно новичок в Dagger. Я пытался реализовать субкомпонент, но все же он не работает, потому что все примеры, которые я искал до сих пор, не использовали DaggerApplication, DaggerAppCompatActivity и мой способ инъекции. Пожалуйста, предложите какое-либо решение или, если подкомпонентный путь правильный, пожалуйста, покажите мне, как это сделать, если это возможно в моей текущей архитектуре.

Большое спасибо заранее.

1 Ответ

0 голосов
/ 19 апреля 2020

@ silaros88 Я столкнулся с той же проблемой, поделился ViewModel между несколькими фрагментами в одном приложении Activity , и я решил поиграть с ViewmModelStoreOwner.

Шагами, чтобы исправить вашу проблема.

  • Смотрите здесь TasksFragment.kt как они вводят ViewModelProvider.Factory вместо ViewModel
  • Получите желаемую ViewModel, используя один из этих двух вариантов:

    • viewModels<SharedDesireViewModel> (requireActivity()) { Injected ViewModelProvider.Factory }
    • ViewModelProvider(requireActivity(), Injected ViewModelProvider.Factory ).get(SharedDesireViewModel::class.java)

Примеры:

Вариант № 1:

FragmentA.kt

class FragmentA: DaggerFragment() {

    @Inject
    lateinit var viewModelProviderFactory: ViewModelProvider.Factory

    private val mainViewModel: MainViewModel by viewModels({requireActivity()}) { viewModelProviderFactory }

    ......

FragmentB.kt

class FragmentB: DaggerFragment() {

    @Inject
    lateinit var viewModelProviderFactory: ViewModelProvider.Factory

    private val mainViewModel: MainViewModel by viewModels({requireActivity()}) { viewModelProviderFactory }

    ......

Вариант № 2:

FragmentA.kt

class FragmentA: DaggerFragment() {

    @Inject
    lateinit var viewModelProviderFactory: ViewModelProvider.Factory

    private val mainViewModel: MainViewModel by lazy {
    ViewModelProvider(requireActivity(), viewModelProviderFactory)
        .get(MainViewModel::class.java)
    }

    ......

FragmentB.kt

class FragmentB: DaggerFragment() {

    @Inject
    lateinit var viewModelProviderFactory: ViewModelProvider.Factory

    private val mainViewModel: MainViewModel by lazy {
    ViewModelProvider(requireActivity(), viewModelProviderFactory)
        .get(MainViewModel::class.java)
    }

    ......
...