Search code examples
androidandroid-architecture-componentsandroid-architecture-navigation

How to make a navigation graph for bottom navigation ? and is there a way to modify the back stack behavior?


I'm new to the navigation architecture component and am trying to make a bottom navigation view. I'm really confused about how should I implement my navigation graph the right way. In addition, I want to make the back stack gets back to the "home" fragment then exists instead of navigating all the back stack.

My app consists of three fragments for bottom navigation. What I've tried to do that I've linked the fragments in every possible combination in the graph. The result was not catastrophic but am still not sure if this is the right way to do it. In addition, when am using the back button of the device the app navigates through every single fragment I've navigated through before exiting the app.

I want to make the navigation so that for the first back button, it navigates back to the first fragment - the start point - then for the second one exists the app.

Here's the code of the navigation graph

    <?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"
    app:startDestination="@id/bottom_navigation_home">

    <fragment
        android:id="@+id/bottom_navigation_home"
        android:name="com.app.albaladinn.view.ui.HomeFragment"
        android:label="fragment_home"
        tools:layout="@layout/fragment_home" >
        <action
            android:id="@+id/action_homeFragment_to_couponsFragment"
            app:destination="@id/bottom_navigation_coupons" />
        <action
            android:id="@+id/action_homeFragment_to_settingsFragment"
            app:destination="@id/bottom_navigation_settings" />
        <action
            android:id="@+id/action_homeFragment_to_categoriesFragment"
            app:destination="@id/bottom_navigation_categories" />
    </fragment>
    <fragment
        android:id="@+id/bottom_navigation_coupons"
        android:name="com.app.albaladinn.view.ui.CouponsFragment"
        android:label="fragment_coupons"
        tools:layout="@layout/fragment_coupons" >
        <action
            android:id="@+id/action_couponsFragment_to_homeFragment"
            app:destination="@id/bottom_navigation_home" />
        <action
            android:id="@+id/action_couponsFragment_to_settingsFragment"
            app:destination="@id/bottom_navigation_settings" />
        <action
            android:id="@+id/action_couponsFragment_to_categoriesFragment"
            app:destination="@id/bottom_navigation_categories" />
    </fragment>
    <fragment
        android:id="@+id/bottom_navigation_settings"
        android:name="com.app.albaladinn.view.ui.SettingsFragment"
        android:label="fragment_settings"
        tools:layout="@layout/fragment_settings" >
        <action
            android:id="@+id/action_settingsFragment_to_couponsFragment"
            app:destination="@id/bottom_navigation_coupons" />
        <action
            android:id="@+id/action_settingsFragment_to_homeFragment"
            app:destination="@id/bottom_navigation_home" />
        <action
            android:id="@+id/action_settingsFragment_to_categoriesFragment"
            app:destination="@id/bottom_navigation_categories" />
    </fragment>
    <fragment
        android:id="@+id/bottom_navigation_categories"
        android:name="com.app.albaladinn.view.ui.CategoriesFragment"
        android:label="fragment_categories"
        tools:layout="@layout/fragment_categories">
        <action
            android:id="@+id/action_categoriesFragment_to_couponsFragment"
            app:destination="@id/bottom_navigation_coupons" />
        <action
            android:id="@+id/action_categoriesFragment_to_homeFragment"
            app:destination="@id/bottom_navigation_home"
            app:popUpToInclusive="false" />
        <action
            android:id="@+id/action_categoriesFragment_to_settingsFragment"
            app:destination="@id/bottom_navigation_settings" />
    </fragment>
</navigation>

and here's the main activity

public class MainNavigationActivity extends AppCompatActivity {

    BottomNavigationView mainBottomNavigation;
    MainBottomNavigationControl mainBottomNavigationControl;
    NavController navController;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_navigation);
        navController = Navigation.findNavController(this, R.id.frame_container);
        mainBottomNavigation = findViewById(R.id.bottom_navigation);
        NavigationUI.setupWithNavController(mainBottomNavigation, navController);
        mainBottomNavigationControl = new MainBottomNavigationControl();
        mainBottomNavigation.setOnNavigationItemSelectedListener(mainBottomNavigationControl);
    }

    class MainBottomNavigationControl implements 
            BottomNavigationView.OnNavigationItemSelectedListener {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            switch (item.getItemId()) {
                case R.id.bottom_navigation_home:
                    navController.navigate(R.id.bottom_navigation_home);
                    return true;
                case R.id.bottom_navigation_categories:
                    navController.navigate(R.id.bottom_navigation_categories);
                    return true;
                case R.id.bottom_navigation_coupons:
                    navController.navigate(R.id.bottom_navigation_coupons);
                    return true;
                case R.id.bottom_navigation_settings:
                    navController.navigate(R.id.bottom_navigation_settings);
                    return true;
                default:
                    return false;
            }
        }
    }
}

Solution

  • NavigationUI.setupWithNavController(mainBottomnavigation, navController) already creates the proper OnNavigationItemSelectedListener for you, so you should remove your MainBottomNavigationControl entirely - it is unneeded.