简体   繁体   English

"如何在不绑定到 ViewModel (MVVM) 中的 UI 的情况下使用 android 导航?"

[英]How to use android navigation without binding to UI in ViewModel (MVVM)?

I am using android navigation that was presented at Google I\/O 2018 and it seems like I can use it by binding to some view or by using NavHost<\/code> to get it from Fragment.我正在使用在 Google I\/O 2018 上展示的 android 导航,似乎我可以通过绑定到某个视图或使用NavHost<\/code>从 Fragment 获取它来使用它。 But what I need is to navigate to another specific view from ViewModel from my first fragment depending on several conditions.但我需要的是根据几个条件从我的第一个片段从 ViewModel 导航到另一个特定视图。 For ViewModel<\/code> , I extend AndroidViewModel<\/code> , but I cannot understand how to do next.对于ViewModel<\/code> ,我扩展了AndroidViewModel<\/code> ,但我不明白下一步该怎么做。 I cannot cast getApplication<\/code> to Fragment\/Activity and I can't use NavHostFragment<\/code> .我无法将getApplication<\/code>转换为 Fragment\/Activity ,也无法使用NavHostFragment<\/code> 。 Also I cannot just bind navigation to onClickListener<\/code> because the startFragment<\/code> contains only one ImageView<\/code> .此外,我不能只将导航绑定到onClickListener<\/code> ,因为startFragment<\/code>只包含一个ImageView<\/code> 。 How can I navigate from ViewModel<\/code> ?如何从ViewModel<\/code>导航?

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(){
    //??
}

}

How can I navigate from ViewModel? 如何从ViewModel导航?

The answer is please don't. 答案是请不要。 ViewModel is designed to store and manage UI-related data. ViewModel旨在存储和管理与UI相关的数据。

New Answer 新答案

In my previous answers, I said that we shouldn't navigate from ViewModel, and the reason is because to navigate, ViewModel must have references to Activities/Fragments, which I believe (maybe not the best, but still I believe it) is never a good idea. 在我之前的回答中,我说我们不应该从ViewModel导航,原因是因为导航,ViewModel必须引用Activities / Fragments,我相信(也许不是最好的,但我仍然相信它)永远不会一个好主意。

But, in recommended app architecture from Google, it mentions that we should drive UI from model . 但是,在Google推荐的应用程序架构中,它提到我们应该从模型中驱动UI And after I think, what do they mean with this? 在我想之后,他们对此有何意义?

So I check a sample from "android-architecture", and I found some interesting way how Google did it. 所以我查看了“android-architecture”中的一个示例,我发现了Google如何做到这一点的有趣方式。

Please check here: todo-mvvm-databinding 请在这里查看: todo-mvvm-databinding

As it turns out, they indeed drive UI from model . 事实证明,他们确实从模型中驱动UI But how? 但是怎么样?

  1. They created an interface TasksNavigator that basically just a navigation interface. 他们创建了一个接口TasksNavigator ,它基本上只是一个导航界面。
  2. Then in the TasksViewModel , they have this reference to TaskNavigator so they can drive UI without having reference to Activities / Fragments directly. 然后在TasksViewModel中 ,他们有对TaskNavigator的引用,因此他们可以直接驱动UI而无需引用Activities / Fragments。
  3. Finally, TasksActivity implemented TasksNavigator to provide detail on each navigation action, and then set navigator to TasksViewModel. 最后,TasksActivity实现了TasksNavigator以提供每个导航操作的详细信息,然后将导航器设置为TasksViewModel。

There are two ways I can recommend doing this.有两种方法我可以推荐这样做。

  1. Use LiveData to communicate and tell the fragment to navigate.使用 LiveData 进行通信并告诉片段导航。
  2. Create a class called Router and this can contain your navigation logic and reference to the fragment or navigation component.创建一个名为 Router 的类,它可以包含您的导航逻辑和对片段或导航组件的引用。 ViewModel can communicate with the router class to navigate. ViewModel 可以与路由器类进行通信以进行导航。

You can use an optional custom enum type and observe changes in your view:您可以使用可选的自定义枚举类型并观察视图中的变化:

enum class NavigationDestination {
    SHOW_TOUR, SHOW_CODE_FRAGMENT
}

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

    private val _destination = MutableLiveData<NavigationDestination?>(null)
    val destination: LiveData<NavigationDestination?> get() = _destination
    
    fun setDestinationToNull() {
        _destination.value = null
    }
    

    fun start(){
        if(dealerProfile.getOperatorId().isEmpty()){
            if(dealerProfile.isFirstTimeLaunch()){
                Log.d(TAG, "First Time Launch")
                _destination.value = NavigationDestination.SHOW_TOUR
            }else{
                _destination.value = NavigationDestination.SHOW_CODE_FRAGMENT
                Log.d(TAG, "Show Code Fragment")

            }
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 Android 中使用 MVVM 数据绑定验证表单 ViewModel? - How to validate form ViewModel with MVVM Data binding in Android? MVVM(数据绑定)中的ViewModel与Android建筑组件中的ViewModel有何不同 - How ViewModel in MVVM (data binding) is differ from ViewModel in Android Architectural components 在 Android 的 MVVM 模式中是否必须使用 ViewModel 和实时数据类? 否则我们可以使用 MVVM 模式而不使用它们吗? - Is it mandatory to use ViewModel and Live Data Classes in MVVM Pattern in Android? Else can we use MVVM pattern without using them? 如何在MVVM Android中使用数据绑定处理ViewModel中的onClick或onTouch之类的事件 - How to handle onClick or onTouch like events in ViewModel with data binding in MVVM Android UI 重复设置 - 数据绑定、MVVM、导航组件 - UI getting set repeatedly - Data binding, MVVM, Navigation Components Android MVVM - 如何在 ViewModel 中引用 Activity - Android MVVM - How to reference Activity in ViewModel 如何在 Android MVVM ViewModel 中获取上下文 - How to get Context in Android MVVM ViewModel Android的ViewModel和MVVM - Android's ViewModel and MVVM Android MVVM 对话框视图模型 - Android MVVM dialog viewmodel mvvm中的Android ViewModel管理 - Android ViewModel management in mvvm
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM