此bounty已结束,回答此问题可获得+50声望奖励,奖励宽限期10小时后结束,krtkush希望引起更多关注此问题:我的目标是在我的android代码中实现Clean Architecture,从而将导航隔离在自己的层中。因此,我希望从ViewModel而不是从UI调用导航调用。
我正在尝试将navController
注入到ViewModel中-
视图模型-
@HiltViewModel
class DeviceHolderListViewModelImpl @Inject constructor(
private val fetchUsersUseCase: FetchUsersUseCase,
private val navigationUtil: NavigationUtil
) : DeviceHolderListViewModel, ViewModel() {
// Trying to access navigationUtil here
}
导航实用程序
class NavigationUtil @Inject constructor(private val navController: NavController) {
fun navigateTo(destination: String, bundle: Bundle) {
when(destination) {
DEVICE_HOLDER_LIST -> navController.navigate(R.id.action_global_goto_deviceHolderListFragment, bundle)
DEVICE_HOLDER_DETAILS -> navController.navigate(R.id.action_global_goto_deviceHolderDetailsFragment, bundle)
}
}
fun navigateBack() {
navController.popBackStack()
}
}
导航模块-
@Module
@InstallIn(ActivityComponent::class)
object NavigationModule {
@Provides
fun provideNavController(activity: AppCompatActivity): NavController {
return Navigation.findNavController(activity, R.id.nav_host_fragment)
}
@Provides
fun provideNavigationUtil(navController: NavController): NavigationUtil {
return NavigationUtil(navController)
}
}
在尝试构建代码时,我得到以下错误-
error:[Dagger/MissingBinding] androidx.navigation.NavController无法在没有@Inject构造函数或@Provides-annotated方法的情况下提供。
是因为我试图从ViewModel
访问navController
,而它应该从片段或Activity访问吗?
我的目标是从ViewModel开始导航。我应该怎样做呢?
3条答案
按热度按时间41zrol4v1#
你不能用Hilt直接注入
NavController
,因为你只能从Activity/Fragment调用Navigation.findNavController
,但是你正在使用的NavigationUtil
方法是一个很好的方法,可以从ViewModel访问导航。你只需要做一些改变:
setNavController
和clearNavController
,而不是将NavController
作为NavigationUtil
的参数传递。NavigationUtil
的作用域设置为ViewModel,并使用@ViewModelScoped
注解provide方法。NavigationUtil
注入Activity,并在onCreate
方法中调用setNavController
,在onDestroy
方法中调用clearNavController
。现在,您的
NavigationUtil
可以访问NavController
,当Activity被重新创建时,它会被更新(当Activity被销毁时,它会被清除),您可以从ViewModel访问它。你可以在这里查看我对一个非常相似的问题的答案:如何使用hilt将jetpack compose中的
rememberNavController
注入到Activity中?zzwlnbp82#
es,您看到的错误消息表明Dagger无法向NavigationUtil类提供NavController的示例。这可能是因为NavController通常与片段或Activity相关联,并且Dagger不清楚如何在视图模型的上下文中提供它。您可以采取的一种方法是在视图模型中定义一个表示导航事件的接口,然后让你的片段/Activity实现该接口并处理导航事件。例如:
vwkv1x7d3#
我会建议一个不同的方法。
我通常创建一个
Navigatior
类,它同时注入到Activity
和ViewModel
中。ViewModel
调用navigator方法,Activity订阅它们。免责声明:以下代码是根据我的记忆写的,语法可能不正确。请随时改进。