Представление не имеет установленного NavController при использовании Фрагмент Фабрика и Компонент навигации - PullRequest
0 голосов
/ 23 апреля 2020

Я реорганизую свое приложение, чтобы использовать Fragment Factory. До рефакторинга все работало нормально с компонентами навигации, но теперь фрагменты больше не могут найти Nav Controller, ошибка:

java.lang.IllegalStateException: View androidx.constraintlayout.widget.ConstraintLayout{7c24bdc V.E...... ......I. 0,0-1080,2088 #7f0a0061 app:id/auth_nav_host_fragment} does not have a NavController set
    at androidx.navigation.Navigation.findNavController(Navigation.java:84)
    at androidx.navigation.fragment.NavHostFragment.findNavController(NavHostFragment.java:118)
    at androidx.navigation.fragment.FragmentKt.findNavController(Fragment.kt:29)
    at com.kalianey.oneness.ui.auth.LauncherFragment.navLogin(LauncherFragment.kt:42)
    at com.kalianey.oneness.ui.auth.LauncherFragment.access$navLogin(LauncherFragment.kt:16)
    at com.kalianey.oneness.ui.auth.LauncherFragment$onViewCreated$1.onClick(LauncherFragment.kt:28)

Я создал фабрику фрагментов:

@AuthScope
class AuthFragmentFactory
@Inject
constructor(
private val viewModelFactory: ViewModelProvider.Factory
) : FragmentFactory() {

override fun instantiate(classLoader: ClassLoader, className: String) =

    when (className) {

        OnboardingPagerFragment::class.java.name -> {
            OnboardingPagerFragment()
        }

        OnboardingOneFragment::class.java.name -> {
            OnboardingOneFragment()
        }

        OnboardingTwoFragment::class.java.name -> {
            OnboardingTwoFragment()
        }

        OnboardingThreeFragment::class.java.name -> {
            OnboardingThreeFragment()
        }

        LauncherFragment::class.java.name -> {
            LauncherFragment(viewModelFactory)
        }

        LoginFragment::class.java.name -> {
            LoginFragment(viewModelFactory)
        }

        RegisterFragment::class.java.name -> {
            RegisterFragment(viewModelFactory)
        }

        ForgotPasswordFragment::class.java.name -> {
            ForgotPasswordFragment(viewModelFactory)
        }

        else -> {
            LauncherFragment(viewModelFactory)
        }
    }

 }

При условии, как это в моем модуле:

@JvmStatic
@AuthScope
@Provides
fun provideFragmentFactory(viewModelFactory: ViewModelProvider.Factory, requestManager: RequestManager, sessionManager: SessionManager): FragmentFactory{
    return AuthFragmentFactory(viewModelFactory)
}

И я настроил его так в своей AuthActivity:

override fun onCreate(savedInstanceState: Bundle?) {
    inject()
    supportFragmentManager.fragmentFactory = fragmentFactory
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_auth)
}

Что я делаю не так?

1 Ответ

1 голос
/ 23 апреля 2020

Когда вы устанавливаете FragmentFactory, он отвечает за создание экземпляра каждого фрагмента AuthActivity. Однако, когда система пытается создать экземпляр NavHostFragment, ваша фабрика создает вместо него LauncherFragment. Это означает, что вы на самом деле никогда не создавали NavHostFragment, и у вас нет NavController.

Вместо создания LauncherFragment, ваш else кейс должен создать тот класс фрагмента, который был запрошен.

else -> {
    super.instantiate(classLoader, className)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...