Как передать аргумент для детализации ViewModel через navArgs - PullRequest
0 голосов
/ 08 апреля 2020

У меня есть экран с RecyclerView подкастов, где, когда вы нажимаете один из них, вы переходите на подробный экран для этого конкретного подкаста. Используя Kodein для внедрения ViewModel, как я могу передать идентификатор подкаста, который был нажат из фрагмента списка, в ViewModel фрагмента фрагмента, чтобы его можно было извлечь из API?

Структура ViewModel структуры выглядит следующим образом :

class PodcastDetailViewModel internal constructor(
    private val podcastRepository: PodcastRepository,
    podcastId: String = ""
): ViewModel() {
    // viewmodel stuff
}

Фрагмент детали выглядит следующим образом:

class PodcastDetailFragment : ScopedFragment(), KodeinAware {
    override val kodein by closestKodein()
    private val args: PodcastDetailFragmentArgs by navArgs()
    private val viewModelFactory: PodcastDetailViewModelFactory by kodein.newInstance { PodcastDetailViewModelFactory(args.podcastId, instance()) }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        viewModel = viewModelFactory.create(PodcastDetailViewModel::class.java)
    }

    // other stuff
}

И вот как я перемещаюсь к экрану подробностей из списка:

private fun navigateToPodcastDetailFragment(podcastId: String) {
        val args = Bundle()
        args.putString("podcast_id", podcastId)

        val directions =
            TopPodcastsFragmentDirections.viewPodcastDetails(
                podcastId
            )
        val extras = FragmentNavigatorExtras(
            podcast_image to "podcastImage_$podcastId"
        )

        Navigation.findNavController(requireActivity(), R.id.nav_host_fragment)
            .navigate(directions, extras)
    } 

Вот как я его связываю:

bind() from provider { PodcastDetailViewModelFactory(instance(), instance()) }

Я не уверен, как связать этот строковый параметр в конструкторе ViewModelFactory или как еще передать туда данные, поэтому любая помощь будет очень полезна. оценили.

Ответы [ 2 ]

1 голос
/ 08 апреля 2020

Вы можете использовать фабрику для своих привязок:

bind() from factory { podcastId: String -> 
    PodcastDetailViewModelFactory(podcastId, instance()) 
}

вызывая ее на месте с:

private val viewModelFactory: PodcastDetailViewModelFactory by instance(arg = args.podcastId) 

надеюсь, это поможет.

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

Я исправил это, переключившись на заводскую привязку, как предложил romainbsl, но вызов во фрагменте был немного другим.

Связывание стало:

bind() from factory { podcastId: String -> 
    PodcastDetailViewModelFactory(podcastId, instance()) 
}

и вызова стал:

private val viewModelFactory: PodcastDetailViewModelFactory by instance(arg = args.podcastId)
...