如何使用Android导航而不绑定到ViewModel(MVVM)中的UI?

Eka*_*nko 7 android mvvm kotlin android-navigation android-jetpack

我正在使用在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(){
    //??
}

}
Run Code Online (Sandbox Code Playgroud)

我的片段

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()

}

}
Run Code Online (Sandbox Code Playgroud)

我想在ViewModel中保留导航逻辑

Yos*_*aya 11

如何从 ViewModel 导航?

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

新答案

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

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

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

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

事实证明,它们确实从模型驱动 UI。但是如何?

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

  • ViewModel 是导航的正确位置,只是在 Android 中成为问题,因为我们需要访问视图来执行此导航。也没有很好的方法来抽象导航。所以,一般来说,Android 上的 VM 不能轻松完成导航,但在其他平台上可以。 (9认同)
  • 为什么应用程序的导航状态是视图的责任?View 的职责是显示数据,而不是知道接下来要显示什么屏幕。 (3认同)
  • 我可能是错的或晚了,但该策略是否会将视图的引用传递给视图模型?这可能会导致内存泄漏 (3认同)
  • 我没有说这是View的责任。但这也不是 ViewModel 的责任。浏览 ViewModel 从来都不是一个好主意。 (2认同)