Кинжал обеспечивает зависимость, которая зависит от вида деятельности - PullRequest
0 голосов
/ 19 сентября 2018

У меня есть активность с навигационным блоком и множеством фрагментов.Я использую библиотеку навигации из компонентов архитектуры.В каждом фрагменте я должен написать navController = Navigation.findNavController(activity!!, R.id.fragment_container).Я хочу избавиться от этого стандартного кода.Поэтому я решаю внедрить его с помощью Dagger.

@Module
class MainActivityModule {
    @ActivityScope
    @Provides
    fun provideNavController(activity: MainActivity): NavController {
        return Navigation.findNavController(activity, R.id.fragment_container)
    }
}

@Suppress("unused")
@Module
abstract class ActivityBuildersModule {
    @ActivityScope
    @ContributesAndroidInjector(
            modules = [MainActivityModule::class, MainActivityFragmentBuildersModule::class])
    abstract fun contributeMainActivity(): MainActivity
}

Впрыск во фрагменты работает нормально, но когда я пытаюсь внедрить в активность приложения, происходит сбой:

09-19 19:22:37.152 22342-22342/com.dmitrysimakov.gymlab
    E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.dmitrysimakov.gymlab, PID: 22342
java.lang.RuntimeException: Unable to start activity
    ComponentInfo{com.dmitrysimakov.gymlab/com.dmitrysimakov.gymlab.MainActivity}:
    java.lang.IllegalArgumentException: ID does not reference a View inside this Activity
    .....

Поэтому мне нужно продублировать navController = Navigation.findNavController(activity!!, R.id.fragment_container) в деятельности.Есть ли более элегантный способ сделать это?

1 Ответ

0 голосов
/ 19 сентября 2018

Сбой приложения из-за активности, потому что когда вызывается provideNavController, вы еще не настроили представление контента, используя setContentView

шаг 1: Если ваш расширяющий DaggerAppCompatActivity копирует свой код и расширяет AppCompatActivity, в противном случаепросто выполните шаг 2.

шаг 2: переместите AndroidInjection.inject(this) строку из onCreate метода после setContentView(...)

Но по моему опыту это может привести к другим проблемам, таким как это , поэтому для получения вашего контроллера навигации от вашей деятельности лучшим выбором может быть просто использование расширения, а на самом деле есть встроенное, если у вас есть зависимость 'android.arch.navigation:navigation-ui-ktx:1.0.0-alpha05' в вашем build.gradle:

findNavController(R.id.fragment_container)

Так что для своей деятельности вы можете использовать это расширение, и в любом случае, если вы используете способ, рекомендованный для одной активности, в большинстве случаев вы получите навигацию по фрагменту и там вы все равно можете использовать инъекцию кинжала

...