首页 > 解决方案 > Android Navigation Advanced Sample Dependency Injection (Hilt) on config changes 问题

问题描述

Google 开发人员提供的Navigation Advanced Sample存在问题。主要问题是,在 Hilt 依赖注入的常规情况下,我们可以简单地:

  1. 创建自定义FragmentFactory
  2. 创建自定义NavHostFragment
  3. FragmentContainerView通过使用将其分配给android:name="com.package.CustomNavHostFragment"

但是我如何使用这个Navigation Advanced Sample来做到这一点?

因为现在在重新创建活动时我得到了典型的 HILTerror at package.MainActivity.onCreate(MainActivity.kt:23)

编辑:

更多关于这个问题。通过这个提供的简单,我们应该使用 NavigationExtension.kt并使用BottomNavigationView.setupWithNavController

问题是我们需要使用默认值NavHostFragment来为每个导航图创建一个容器。是否有可能以某种方式使用 custom NavHostFragment?如果是,我怎样才能覆盖该NavHostFragment.onCreate()机制?我说的是NavigationExtension.kt类中的这一行

标签: androidkotlinnavigationandroid-bottomnav

解决方案


如果我正确理解了您的问题,您想创建一个自定义NavHostFragment?是的,这是可能的,但您不需要覆盖NavHostFragment.onCreate(). NavHostFragment通过以下步骤创建自定义:首先,创建一个MainFragmentFactory

MainFragmentFactory

class MainFragmentFactory @Inject constructor(
    //... your dependencies
) : FragmentFactory() {
    override fun instantiate(classLoader: ClassLoader, className: String): Fragment = when(className) {
        MyFragment::class.java.name -> MyFragment(//.. your dependencies)
        MySecondFragment::class.java.name -> MySecondFragment(/...)
        // other fragments

        else -> super.instantiate(classLoader, className)
    }
}

然后您需要将您的 fragmentFractory 附加到您的自定义MainNavHostFragment

MainNavHostFragment

@AndroidEntryPoint
class MainNavHostFragment : NavHostFragment() {

    @Inject
    lateinit var mainFragmentFactory: MainFragmentFactory

    override fun onAttach(context: Context) {
        super.onAttach(context)
        childFragmentManager.fragmentFactory = mainFragmentFactory
    }
}

现在您需要将自定义添加NavHostFragment到您的activity_main.xml

Activity_main.xml

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".framework.ui.view.MainActivity">

    <fragment
        android:id="@+id/fragment_container"
        <!-- Add path to your custom NavHostFragment here -->
        android:name="com.example.app.framework.ui.view.utils.MainNavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="@dimen/wrapContent"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toTopOf="@+id/bottomNavigationView"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        <!-- Your NavGraph -->
        app:navGraph="@navigation/nav_main" />

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottomNavigationView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:itemHorizontalTranslationEnabled="false"
        app:labelVisibilityMode="labeled"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:menu="@menu/bottom_nav_menu_logged_out" />
</androidx.constraintlayout.widget.ConstraintLayout>

Dagger-Hilt 现在将创建所有片段并实例化它。


推荐阅读