androidandroid-studiokotlinandroid-architecture-navigation

Using navigation component with bottom navigation bar by using FragmentContainerView tag


I have already looked this question: FragmentContainerView using findNavController about this problem. But however I stiil couldn't solve the problem. It never opens other fragments. I thought maybe it is because of view binding but I tried to do it again without using view binding. It doesn't open still.

MainActivity.kt

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding

    private lateinit var navController: NavController
    private lateinit var navHostFragment: NavHostFragment

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        val view = binding.root
        setContentView(view)

        val navHostFragment =
            supportFragmentManager.findFragmentById(R.id.main_nav_host_fragment) as NavHostFragment
        navController = navHostFragment.navController
        binding.bottomNavigationView.setupWithNavController(navController)
        
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.home -> {
                navHostFragment.navController.popBackStack()
                return true
            }
        }
        return super.onOptionsItemSelected(item)
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<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=".MainActivity">

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/main_nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_graph_main" />
    

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottomNavigationView"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        app:menu="@menu/menu"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

nav_graph_main

<?xml version="1.0" encoding="utf-8"?>
<navigation 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:id="@+id/nav_graph_main"
    app:startDestination="@id/fragmentLibrary">

    <fragment
        android:id="@+id/fragmentLibrary"
        android:name="com.project.biosec.FragmentLibrary"
        android:label="fragment_library"
        tools:layout="@layout/fragment_library" />
    <fragment
        android:id="@+id/fragmentTransaction"
        android:name="com.project.biosec.FragmentTransaction"
        android:label="fragment_transaction"
        tools:layout="@layout/fragment_transaction" />
    <fragment
        android:id="@+id/fragmentAccount"
        android:name="com.project.biosec.FragmentAccount"
        android:label="fragment_account"
        tools:layout="@layout/fragment_account" >
        <action
            android:id="@+id/action_fragmentAccount_to_changeSignatureFragment"
            app:destination="@id/changeSignatureFragment" />
        <action
            android:id="@+id/action_fragmentAccount_to_securityFragment"
            app:destination="@id/securityFragment" />
        <action
            android:id="@+id/action_fragmentAccount_to_helpFragment"
            app:destination="@id/helpFragment" />
        <action
            android:id="@+id/action_fragmentAccount_to_termsFragment"
            app:destination="@id/termsFragment" />
    </fragment>
    <fragment
        android:id="@+id/changeSignatureFragment"
        android:name="com.project.biosec.ChangeSignatureFragment"
        android:label="fragment_change_signature"
        tools:layout="@layout/fragment_change_signature" />
    <fragment
        android:id="@+id/securityFragment"
        android:name="com.project.biosec.SecurityFragment"
        android:label="fragment_security"
        tools:layout="@layout/fragment_security" />
    <fragment
        android:id="@+id/helpFragment"
        android:name="com.project.biosec.HelpFragment"
        android:label="fragment_help"
        tools:layout="@layout/fragment_help" />
    <fragment
        android:id="@+id/termsFragment"
        android:name="com.project.biosec.TermsFragment"
        android:label="fragment_terms"
        tools:layout="@layout/fragment_terms" />
</navigation>

menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/feed_fragment"
        android:icon="@drawable/ic_library"
        android:title="@string/library" />

    <item
        android:id="@+id/messages_fragment"
        android:icon="@drawable/ic_assignment"
        android:title="@string/transactions" />

    <item
        android:id="@+id/profile_fragment"
        android:icon="@drawable/ic_account"
        android:title="@string/account" />
</menu>

Solution

  • As per the Setting up bottom navigation guide:

    Note: Setting up bottom navigation requires that you also set up your navigation graph and menu xml as described in Tie destinations to menu items.

    That section specifically states that the android:id of your destination in your navigation graph XML file needs to match the android:id of the menu item in your menu XML file.

    In your case, your navigation XML uses android:id="@+id/fragmentLibrary", android:id="@+id/fragmentTransaction", and android:id="@+id/fragmentAccount", so your menu items should change to use those same IDs.