Search code examples
androidlayoutnavigationincludefragment

Android View Binding: When accessing NavHostFragment from included xml layout


I have activity_main.xml, with ViewBinding enabled generates ActivityMainBinding Class perfectly. I have another content_main.xml layout which is included in this layout as below:

activity_main.xml

 <androidx.coordinatorlayout.widget.CoordinatorLayout
        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=".MainActivity">

        <com.google.android.material.appbar.AppBarLayout
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:theme="@style/AppTheme.AppBarOverlay">

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                app:popupTheme="@style/AppTheme.PopupOverlay" />

        </com.google.android.material.appbar.AppBarLayout>

        <include layout="@layout/content_main"
            android:id="@+id/main_container"/>
    </androidx.coordinatorlayout.widget.CoordinatorLayout>

Here is content_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"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.example.varshakulkarni.videorecordwithlyricspoc.MainActivity"
    tools:showIn="@layout/activity_main">

    <!--This layout is created to place all the content below the AppBar without overlapping while scrolling.-->
    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true" />

    <TextView
        android:id="@+id/text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>
<!-- Update: replace this with androidx.fragment.app.FragmentContainerView -->
    <fragment
        android:id="@+id/nav_host"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/navigation" />

</androidx.constraintlayout.widget.ConstraintLayout>

In MainActivity class, while accessing other views like TextViews/Buttons, we can use binding.mainContainer.textView.text = "test" , which works well.

but how do we access androidx.navigation.fragment.NavHostFragment?

Since the fragments are not normal views, get this error, "Cannot access 'android.widget.fragment'. Check your module classpath for missing or conflicting dependencies"

MainActivity.kt

 binding.apply {
            //Works
            mainContainer.textView.text = "test"
            //throws "Cannot access 'android.widget.fragment'. Check your module classpath for missing or conflicting dependencies"
            mainContainer.navHost.postDelayed({
                binding.mainContainer.navHost.systemUiVisibility = FLAGS_FULLSCREEN
            }, IMMERSIVE_FLAG_TIMEOUT)
        }

Update: this works when FragmentContainerView is used.


Solution

  • To host a navGraph , you should use FragmentContainerView instead of Fragment with name attribute set to :

    android:name="androidx.navigation.fragment.NavHostFragment"