从JetPack Compose中的ViewModel导航的正确方法是什么? Hilt+ ViewModel?
我偶然发现了这个非常琐碎但棘手的问题。我花了很多时间搜索官方文档,但不幸的是没有找到答案。
官方文档说,您应该将navcontroller
的实例传递给@composable
-s,并将其称为onclick = {navcontroller.navigate(“ path”) }
。但是,如果我必须从ViewModel触发导航事件(例如,重定向到登录,重定向到新创建的Post Page),会发生什么?等待@composable
中的任何coroutine(ex。http请求)不仅很糟糕,而且可能会迫使Android杀死App,因为被阻止的UI线程
非正式的解决方案(主要记录了中等文章的形式)是基于拥有单身类和观察一些mutableStateFlow
包含路径的概念。
从理论上讲,这听起来很愚蠢,并且在实践中没有太大帮助(副作用和重新组成友好,触发不必要的重新启动)。
I have stumbled upon this quite trivial, but tricky problem. I have spent a decent amount of time searching official docs, but unfortunately found no answer.
Official docs say that you should pass an instance of NavController
down to @Composable
-s, and call it as onClick = { navController.navigate("path") }
. But what happens if I have to trigger navigation event from ViewModel (ex. redirect on login, redirect to newly created post page)? Awaiting any coroutine (ex. HTTP request) in @Composable
would be not just bad, but probably force Android to kill app because of the blocked UI thread
Unofficial solutions (documented mostly if form of Medium articles) are based on the concept of having a singleton class and observing some MutableStateFlow
containing path.
That sounds stupid in theory, and doesn't help much in practice (not side-effect and recomposition friendly, triggers unnecessary re-navigation).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我自己一直在挣扎着完全相同的问题。 特别是体系结构事件部分 i i'我想知道他们的建议是将状态用作导航的触发因素吗?
引用文档:
They have provided the following snippet of code for the above requirement:
What they did not provide is the rest of the view model and compose code. I'm guessing it's supposed to look like:
Also the view model could have a function like this one (trigger by clicking a "sign in" button from compose screen
I have been struggling with the exact same question myself. From the limited documentation Google provided on this topic, specifically the architecture events section I'm wondering if what they're suggesting is to use a state as a trigger for navigation?
Quoting the document:
They have provided the following snippet of code for the above requirement:
What they did not provide is the rest of the view model and compose code. I'm guessing it's supposed to look like:
Also the view model could have a function like this one (trigger by clicking a "sign in" button from compose screen
continue
The
rememberNavController
has a pretty simple source code that you can use to create it in a singleton service:Create a helper view model to share
NavHostController
withNavHost
view:Then in any view model you can inject it and use for navigation:
我的方式比@phil Dukhov类似。我创建了一个包装程序类,该类复制已经在
remame> remamenavcontroller()
中找到的代码:然后使用刀柄我为我的
navHostController
创建了一个提供商。由于我需要navController遍历嵌套navHost
,因此决定将其范围范围范围范围固定到viewModel
这使我可以直接将navController注入我的ViewModel,并从内部触发导航。然后,我可以通过以下方式从我的组件访问NavController:
为了构建嵌套
navgraph
I went a similar way than @Phil Dukhov. I created a wrapper class that copies the code already found in
rememberNavController()
:Then using Hilt I created a provider for my
NavHostController
. As I needed my navController to traverse a nestedNavHost
I decided to scope it to theViewModel
This allows me to inject the navcontroller directly into my viewmodel and trigger navigation from within. I can then access the NavController from my composables in the following way:
in order to build the nested
NavGraph
我已经使用了几个月,但没有遇到任何问题。我喜欢它,因为它很简单。我的产品版本使用Koin注入NavigationManager Singleton(而不是Hilt)。为了简化此示例,我发布了一种基于对象的方法。
I've used this for a few months and haven't encountered any issues. I like it because it's straightforward. My product version uses Koin to inject a NavigationManager singleton (instead of Hilt). To simplify this example, I posted an object-based approach.