用MVVM android导航

Vin*_*ams 13 android mvvm rx-java android-viewmodel android-architecture-navigation

我有一个使用Androids ViewModel类和导航组件的应用程序,用于在片段之间导航.我如何处理ViewModel的导航?我正在使用RxJava,我正在考虑让Fragments监听导航事件,然后以这种方式触发导航.处理这个问题的正常方法是什么?如果有帮助,我也使用Dagger进行依赖注入.

ian*_*ake 7

根据LiveData与SnackBar,导航和其他活动博客文章:

某些数据应该只消耗一次,如Snackbar消息,导航事件或对话框触发器.

它不是试图用架构组件的库或扩展来解决这个问题,而是应该面对一个设计问题.我们建议您将您的活动视为您所在州的一部分.

他们详细介绍了SingleLiveEvent类的使用,该类确保每个Navigation事件仅由Observer接收一次(即,您的Fragment可以访问您的NavController).

另一种方法是使用"事件包装器"模型,其中事件必须明确标记为已处理.

  • 虽然我同意这是官方推荐,但我认为谷歌在这里犯了一个大错.导航不是特定视图模型的"状态"的一部分,也不是事件.它是它自己的实体(我喜欢将它视为一种服务),它可能包含它自己的状态和事件.他们需要为此发明一个SingleLiveEvent这一事实证明了这一点. (3认同)
  • https://medium.com/google-developer-experts/using-navigation-architecture-component-in-a-large-banking-app-ac84936a42c2 有一个从 ViewModel 发布导航事件的干净实现 (3认同)

And*_*sch 3

如果您使用 MVP,P 将仅调用 V 上触发导航的方法。

MVVM 中的等效方法是拥有一个专用的可观察/侦听器/回调,如果使用 RxJava 完成,它可以由PublishSubject. 这样就满足了一次性的要求。相反,如果您需要响应在订阅之前可能发出的事件,您可以使用 aBehaviorSubject<Optional<T>>并使用 来创建它createDefault(absent<T>()),使用 来触发它onNext(Optional.of(navigationObject)),然后让虚拟机知道何时发生导航,然后虚拟机可以使用来清除它onNext(absent())

或者,如果您想将其处理为某种包罗万象的 redux/mvi 状状态,您可能有一些状态类,其中包含所有状态,包括一些指示视图导航到某处的属性,在接收/执行此操作时,视图将告诉虚拟机它已经这样做了,虚拟机会将状态设置为与当前相同但没有导航。例如(在 Kotlin 中)state = state.copy(navigateToX = false)