Andrew
Andrew

Reputation: 4712

Android: Dagger hilt, inject navigation component

I am trying to provide my navController with dagger hilt. But the approach I am using does not work. I want to provide the navController in order to Inject it in my fragment via constructor injection.

Without Di.Module, FragmentClass

private val navController by lazy { findNavController() }
private val appBarConf by lazy { AppBarConfiguration(navController.graph) }

Current approach, Di.Module

@Module
@InstallIn(ApplicationComponent::class)
object AndroidModule {

@Provides
fun provideNavController(@ApplicationContext context: Context): NavController = lazy {
    (context as AppCompatActivity).findNavController(R.navigation.nav_main)
}.value

@Provides
fun provideAppbarConfiguration(navController: NavController): AppBarConfiguration = lazy {
    AppBarConfiguration(navController.graph)
}.value
}

I've also created the FragmentFactory class in order to inject my dependency via the constructor. I know that (context as AppCompatActivity) is the problem here, but I don't know the proper solution..

I appreciate every help, thanks!

Error

Caused by: java.lang.ClassCastException: com.example.app.App cannot be cast to androidx.appcompat.app.AppCompatActivity

Upvotes: 1

Views: 9216

Answers (1)

Jeroen Flietstra
Jeroen Flietstra

Reputation: 178

This works for me. The activity should be provided if you install in the ActivityComponent. I'm only injecting into navigators of a Fragment. So that's why I used @InstallIn(ActivityComponent::class)

@Module
@InstallIn(ActivityComponent::class)
object MainActivityModule {

    @Provides
    fun provideNavController(activity: Activity): NavController {
        return activity.findNavController(R.id.navHostFragment)
    }
}

The R.id.navHostFragment is in this case not the id of the navigation graph, but of the fragment host.

Edit: as Andrew pointed out. Don’t forget to annotate your fragment with @AndroidEntryPoint

Upvotes: 6

Related Questions