androidx.navigation.NavController 是否可以使用 DI
Is it possible to use DI with the androidx.navigation.NavController
所以,这个标题反映了这个问题。
要在导航控制器 (androidx.navigation.NavController
) 上获得 link,通常我们使用以下代码:
NavController navController = Navigation.findNavController(this, R.id.nav_host_frag);
是否可以使用 Dagger2
框架 注入 NavController? (findNavController
需要 activity 或视图引用)
也许这是一个愚蠢的问题,没有人注入 androidx.navigation.NavController
,但尽管如此,我还是决定问这个问题来确定我的假设。先谢谢了
为什么这行不通?您可以像添加任何其他对象一样将其添加到组件中
- 通过 Component.Builder 通过
@BindsInstance
或带有参数的模块
- 通过 return 从
@Provides
带注释的方法
使用 @Provides
注释方法,您还需要在组件中提供 Activity 或视图。根据您使用 Dagger 的方式,您通常可以使用特定的 Activity,因此您可以直接使用它,例如对于 MyActivityComponent
和 MyActivity
你可以简单地 return 它在一个模块
@Provides
NavController bindController(MyActivity activity) {
Navigation.findNavController(this, R.id.nav_host_frag)
}
我不明白你为什么要注入 NavController
当有方法供你找到它时,我也会担心使用依赖注入,因为持有对 [= 的引用15=].
鉴于您正在使用 Activity
,您通常会使用以下方法找到控制器:
private val navController: NavController by lazy { findNavController(R.id.main_container) }
现在,如果我们看一下方法 findNavController()
的源代码,您会注意到它使用了扩展函数和 Navigation.findNavController(this, viewId)
.
/**
* Find a [NavController] given the id of a View and its containing
* [Activity].
*
* Calling this on a View that is not a [NavHost] or within a [NavHost]
* will result in an [IllegalStateException]
*/
fun Activity.findNavController(@IdRes viewId: Int): NavController =
Navigation.findNavController(this, viewId)
我唯一要做的就是创建另一个扩展函数以方便从 Fragment
导航。
fun Fragment.navigate(resId: Int, bundle: Bundle? = null) {
NavHostFragment.findNavController(this).navigate(resId, bundle)
}
然后你可以简单地在片段中使用:
navigate(
R.id.action_fragmentA_to_FragmentB,
bundleOf(Global.CAN_NAVIGATE_BACK to false)
)
我已经在
中回答了这个问题
简而言之,
- 通过通常的匕首方式提供
NavController
,例如:
@Provides
fun providesNavController(activity: MainActivity): NavController {
return activity.supportFragmentManager.findFragmentById(R.id.main_content).findNavController()
}
- 从
onAttach
注入 NavController
- 注入
NavController
lazily 以避免 Android 重新创建 Activity
和 NavController
之间的竞争条件检索到:
@Inject
lateinit var navController: Provider<NavController>
所以,这个标题反映了这个问题。
要在导航控制器 (androidx.navigation.NavController
) 上获得 link,通常我们使用以下代码:
NavController navController = Navigation.findNavController(this, R.id.nav_host_frag);
是否可以使用 Dagger2
框架 注入 NavController? (findNavController
需要 activity 或视图引用)
也许这是一个愚蠢的问题,没有人注入 androidx.navigation.NavController
,但尽管如此,我还是决定问这个问题来确定我的假设。先谢谢了
为什么这行不通?您可以像添加任何其他对象一样将其添加到组件中
- 通过 Component.Builder 通过
@BindsInstance
或带有参数的模块 - 通过 return 从
@Provides
带注释的方法
使用 @Provides
注释方法,您还需要在组件中提供 Activity 或视图。根据您使用 Dagger 的方式,您通常可以使用特定的 Activity,因此您可以直接使用它,例如对于 MyActivityComponent
和 MyActivity
你可以简单地 return 它在一个模块
@Provides
NavController bindController(MyActivity activity) {
Navigation.findNavController(this, R.id.nav_host_frag)
}
我不明白你为什么要注入 NavController
当有方法供你找到它时,我也会担心使用依赖注入,因为持有对 [= 的引用15=].
鉴于您正在使用 Activity
,您通常会使用以下方法找到控制器:
private val navController: NavController by lazy { findNavController(R.id.main_container) }
现在,如果我们看一下方法 findNavController()
的源代码,您会注意到它使用了扩展函数和 Navigation.findNavController(this, viewId)
.
/**
* Find a [NavController] given the id of a View and its containing
* [Activity].
*
* Calling this on a View that is not a [NavHost] or within a [NavHost]
* will result in an [IllegalStateException]
*/
fun Activity.findNavController(@IdRes viewId: Int): NavController =
Navigation.findNavController(this, viewId)
我唯一要做的就是创建另一个扩展函数以方便从 Fragment
导航。
fun Fragment.navigate(resId: Int, bundle: Bundle? = null) {
NavHostFragment.findNavController(this).navigate(resId, bundle)
}
然后你可以简单地在片段中使用:
navigate(
R.id.action_fragmentA_to_FragmentB,
bundleOf(Global.CAN_NAVIGATE_BACK to false)
)
我已经在
简而言之,
- 通过通常的匕首方式提供
NavController
,例如:
@Provides
fun providesNavController(activity: MainActivity): NavController {
return activity.supportFragmentManager.findFragmentById(R.id.main_content).findNavController()
}
- 从
onAttach
注入 - 注入
NavController
lazily 以避免 Android 重新创建Activity
和NavController
之间的竞争条件检索到:
NavController
@Inject
lateinit var navController: Provider<NavController>