0

having a problem with Navigation Advanced Sample provided by Google developers. Main problem is that in regular case senario for Hilt dependency injection we can simply:

  1. Create Custom FragmentFactory
  2. Create Custom NavHostFragment
  3. Asigne it to FragmentContainerView by using android:name="com.package.CustomNavHostFragment"

But how I can do it by using this Navigation Advanced Sample ?

Because now on Activity recreate I'm getting typical HILT error at package.MainActivity.onCreate(MainActivity.kt:23)

EDIT:

More about the problem. By this provided simple we should use NavigationExtension.kt and setup everything by using BottomNavigationView.setupWithNavController

And problem is that we need to use the default NavHostFragment in order to create a container for each navigation graph. Is it possible somehow to use custom NavHostFragment? If yes, how can I overite that NavHostFragment.onCreate() mechanism? I'm talking about this line in NavigationExtension.kt class

  • What exactly is your problem? Please describe it better than just providing a link to a big repository.. – Andrew Oct 05 '20 at 20:53
  • Problem: On config changes (rotation, dark/light theme update etc.) my app crashes because I don't use FragmentFactory with custom NavHostFragment. My question how it could by done by using [link](https://github.com/android/architecture-components-samples/tree/main/NavigationAdvancedSample) – Tomas Tosas Oct 06 '20 at 06:37
  • The link just points to the entire repository, I am sorry but one can't analyze all and then provide a solution. Please point to a specific class. And why aren't you using the default way with a `FragmentFactory` and a custom `NavHostFragment`? – Andrew Oct 06 '20 at 08:22

1 Answers1

0

If I understood your problem correctly, you want to create a custom NavHostFragment? Yes, that is possible but you don't need to overwrite NavHostFragment.onCreate(). Create a custom NavHostFragment with the following steps: First, create a 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)
    }
}

Then you need to attach your fragmentFractory to your custom MainNavHostFragment

MainNavHostFragment

@AndroidEntryPoint
class MainNavHostFragment : NavHostFragment() {

    @Inject
    lateinit var mainFragmentFactory: MainFragmentFactory

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

Now you need to add your custom NavHostFragment to your 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 will now create all your fragments and instantiate it.

Andrew
  • 4,264
  • 1
  • 21
  • 65