首页 > 解决方案 > 如何在不绑定到 ViewModel (MVVM) 中的 UI 的情况下使用 android 导航?

问题描述

我正在使用在 Google I/O 2018 上展示的 android 导航,似乎我可以通过绑定到某个视图或使用NavHost从 Fragment 获取它来使用它。但我需要的是根据几个条件从我的第一个片段从 ViewModel 导航到另一个特定视图。对于ViewModel,我扩展AndroidViewModel,但我不明白下一步该怎么做。我无法getApplication转换为 Fragment/Activity,也无法使用NavHostFragment. 此外,我不能只将导航绑定到,onClickListener因为startFragment它只包含一个ImageView. 我该如何导航ViewModel

class CaptionViewModel(app: Application) : AndroidViewModel(app) {
private val dealerProfile = DealerProfile(getApplication())
val TAG = "REGDEB"


 fun start(){
    if(dealerProfile.getOperatorId().isEmpty()){
        if(dealerProfile.isFirstTimeLaunch()){
            Log.d(TAG, "First Time Launch")
            showTour()
        }else{
            showCodeFragment()
            Log.d(TAG, "Show Code Fragment")

        }
    }
}

private fun showCodeFragment(){
    //??
}

private fun showTour(){
    //??
}

}

我的片段

class CaptionFragment : Fragment() {
private lateinit var viewModel: CaptionViewModel
private val navController by lazy { NavHostFragment.findNavController(this) }

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
    viewModel = ViewModelProviders.of(this).get(CaptionViewModel::class.java)
    return inflater.inflate(R.layout.fragment_caption, container, false)
}


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

    viewModel.start()

}

}

我想在 ViewModel 中保留导航逻辑

标签: androidmvvmkotlinandroid-navigationandroid-jetpack

解决方案


如何从 ViewModel 导航?

答案是请不要。ViewModel 旨在存储和管理与 UI 相关的数据。

新答案

在我之前的回答中,我说过我们不应该从 ViewModel 导航,原因是因为要导航,ViewModel 必须引用活动/片段,我相信(可能不是最好的,但我仍然相信)永远不会一个好主意。

但是,在 Google 推荐的应用架构中,它提到我们应该从 model 驱动 UI。在我思考之后,它们是什么意思?

所以我检查了一个来自“android-architecture”的样本,我发现了谷歌是如何做到这一点的一些有趣的方式。

请在此处查看:todo-mvvm-databinding

事实证明,它们确实从 model 驱动 UI。但是怎么做?

  1. 他们创建了一个界面TasksNavigator,基本上只是一个导航界面。
  2. 然后在TasksViewModel中,他们有对 TaskNavigator 的引用,因此他们可以在不直接引用活动/片段的情况下驱动 UI。
  3. 最后,TasksActivity 实现了 TasksNavigator 以提供每个导航操作的详细信息,然后将 navigator 设置为 TasksViewModel。

推荐阅读