【问题标题】:How to pass argument to detail ViewModel via navArgs如何通过 navArgs 将参数传递给详细 ViewModel
【发布时间】:2020-04-07 21:13:58
【问题描述】:

我有一个带有播客 RecyclerView 的屏幕,当您单击其中一个时,它会将您带到该特定播客的详细信息屏幕。使用 Kodein 进行 ViewModel 注入,如何将列表片段中点击的播客的 id 传递给详细片段的 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 构造函数中绑定该字符串参数,或者如何在那里传递数据,因此非常感谢任何帮助。

【问题讨论】:

    标签: android kotlin mvvm kodein


    【解决方案1】:

    您可以使用工厂进行绑定:

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

    在现场调用它:

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

    希望这会有所帮助。

    【讨论】:

    • 我想我可能已经解决了注入问题,但现在我得到了一个 IllegalStateException 因为Fragment has null arguments,我认为这是一个导航组件问题,但我也无法弄清楚
    【解决方案2】:

    我通过切换到工厂绑定来解决这个问题,就像 romainbsl 建议的那样,但是片段中的调用有点不同。

    绑定变成:

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

    现场通话变成了:

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

    【讨论】:

      【解决方案3】:

      试试这个

      private val viewModel by viewModels<PodcastDetailViewModel> {
        val viewModelFactory: PodcastDetailViewModelFactory by instance(arg = args.podcastId)
        viewModelFactory
      }
      

      或

      private val viewModel by activityViewModels<PodcastDetailViewModel> {
        val viewModelFactory: PodcastDetailViewModelFactory by instance(arg = args.podcastId)
        viewModelFactory
      }
      

      【讨论】:

        【解决方案4】:

        试试这个:

        private val viewModelFactory: PodcastDetailViewModelFactory by instance {arg = args.podcastId}
        

        由 Lazy 实例化,因为 navArgs() 是 android.app.Activity.navArgs 和 androidx.fragment.app.Fragment.navArgs 使用的 Lazy 的实现。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-06-08
          • 1970-01-01
          • 1970-01-01
          • 2021-08-31
          • 1970-01-01
          • 2023-03-11
          • 1970-01-01
          相关资源
          最近更新 更多