Search code examples
androidandroid-layoutandroid-fragmentsnavigation-drawerandroid-architecture-navigation

Android: change current content in navigation drawer app, without showing item in drawer menu


I'm a beginner in Android development, and I'd like to create an app with a Navigation Drawer. I started with the default template from the Android Studio 'create project' window.

This is the code from the MainActivity, that sets up the drawer navigation.

@Override
protected void onCreate(Bundle savedInstanceState) {
    
    super.onCreate(savedInstanceState);
    
    setContentView(R.layout.activity_main);
    Toolbar toolbar = findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    DrawerLayout drawer = findViewById(R.id.drawer_layout);
    NavigationView navigationView = findViewById(R.id.nav_view);
    // Passing each menu ID as a set of Ids because each
    // menu should be considered as top level destinations.
    mAppBarConfiguration = new AppBarConfiguration.Builder(
        R.id.nav_customers, R.id.nav_notes, R.id.nav_stats, R.id.nav_settings)
            .setDrawerLayout(drawer)
            .build();
    navController = Navigation.findNavController(this, R.id.nav_host_fragment);
    NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
    NavigationUI.setupWithNavController(navigationView, navController);
}

I've got a fragment that is the 'customers' page. This page contains a button the user can click on to create a new customer. When that button is clicked, a new page should be opened that takes the input for creating the customer. This new page should not be a navigation item the user can navigate to directly. The only way and reason to open that page should be by using the 'create customer' button in the customers view I mentioned.

So, that new page should not be included in the menu of the navigation drawer. At the same time, I do want to give this page its own Toolbar.

The two most important things to do, seem to be:

  • Add a navigation destination / page to the activity. This page should not be included in the navigation drawer's menu. Opening the page should be done programmatically.
  • The page must have its own Toolbar at the top of the screen.

It seems simple and I tried a lot, but I didn't find any solution so far.


Solution

  • You can check the doc:

    Define in your graph something like:

    <fragment android:id="@+id/a"
              android:name="com.example.myapplication.FragmentA"
              android:label="a"
              tools:layout="@layout/a">
        <action android:id="@+id/action_a_to_b"
                app:destination="@id/b"/>
    </fragment>
    <fragment android:id="@+id/b"
              android:name="com.example.myapplication.FragmentB"
              android:label="b"
              tools:layout="@layout/b">
    </fragment>
    

    and then just use to navigate:

    findNavController().navigate(R.id.action_a_to_b)
    

    Check also this page:

    Adding the top app bar to your activity works well when the app bar’s layout is similar for each destination in your app. If, however, your top app bar changes substantially across destinations, then consider removing the top app bar from your activity and defining it in each destination fragment, instead.

    In the FragmentB in the on onCreateView you can inflate your layout

    override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
    ): View? {
        val root = inflater.inflate(R.layout.fragment_B container, false)
    

    In this layout you can put a Toolbar:

    <LinearLayout>
        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            ... />
        ...
    </LinearLayout>
    

    and:

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        val navController = findNavController()
        val appBarConfiguration = AppBarConfiguration(navController.graph)
    
        view.findViewById<Toolbar>(R.id.toolbar)
                .setupWithNavController(navController, appBarConfiguration)
    }
    

    The alternative is to setup the navigation in the Activity and use the OnDestinationChangedListener:

    navController.addOnDestinationChangedListener { _, destination, _ ->
       if(destination.id == R.id.b) {
           toolbar.visibility = View.GONE
           //....
       } else {
           toolbar.visibility = View.VISIBLE
           //.....
       }