Drawer Navigation using Material 3 in Jetpack Compose | by Saqib | Sep, 2023
Explaining Material3 APIs for Navigation Drawer
As mentioned before
Material 3 provides explicit Apis for
Drawer Navigation, first we will see in brief what those APIs are and later will implement them.
The main Composable provided by Material3 is
ModelNavigationDrawer mentioned below.
Let’s see important parameters for
drawerState— It keeps track of the Drawer
Open/Closedstate provided via
gestureEnabled— It provides gesture capability to use swipe gesture from
left -> rightto Open and
right -> leftto Close drawer if it was opened before, we can also disable it as per our need.
drawerContent— Its content of the slider/drawer itself, we will provide a
content— Its the actual page content showing composable screens to the user, we can add
NavHostas content to manage different screens to show from
Material3 provides another composable
ModelDrawerSheet which should be used to provide
drawerContent as it sets all required values required for a Drawer.
Let’s see the
ModelDrawerSheet composable below, later we will see how to use it while creating content for
All of the parameters of
ModelDrawerSheet are self-explanatory, we will look into
content parameter, which is composable for Drawer using that we will provide Drawer composable.
ModelDrawerSheet works as a wrapper for
Drawer content composable providing basic designs and colour schemes following Material 3 design guidelines.
Let’s get started with implementation!
Let’s see the basic implementation of the Drawer in
Below code is showing
Drawer in red and the content page in green, In the next example we will implement a real use-case with Drawer menus list and multiple screens.
As mentioned earlier
ModelNavigationDrawer is the main composable to use providing
drawerContent wrapping it inside
ModelDrawerSheet which you can use to provide any design of your
Above you can see gestures to slide in/out are working for Drawer automatically, it’s because the default value is set
gestureEnabled parameter for
Real use-case implementation
Now Let’s implement an actual use-case where we want to show three screens: Articles, Settings and About Us using
Drawer Navigation Component.
We will be using the Compose
Navigation component. That’s a prerequisite for this story, If you want to read more about it you can read from official documentation here.
In order to use
NavHost we have to provide
routes for our composables and in our case we will have three
routes each for each screen and to express them in code we will use
Enum is enough for our case, we don’t need
Sealed classes just for
Drawer we want to show list of
icon and when user taps on any
menu we want to navigate to that screen using
Material3 provides a built-in composable
NavigationDrawerItem which has default settings and follows Material design guidelines, we will use
NavigationDrawerItemto show menus inside Drawer.
Below is definition for
NavigationDrawerItem is pretty self-explanatory.
In order to use
NavigationDrawerItem we need to create a
Data class which will hold information for individual
Menu items that we want to show inside the
data class will hold
route for the menu as stated below.
Below is the list of menus we will show.
I am passing
titlefor each menu as a
Stringbut in real Application in order to support multi languages, you want to pass title as
resourceIdand annotate it with
At this point we have created everything for menus on
Drawer but we still need a composable for
Drawer content which will eventually contain a list of menus inside and some custom design for the top portion.
So Let’s create
DrawerContent composable as below.
DrawerContent composable is taking a list of
menus and providing a
lambda which will be called when any
menu will be clicked.
DrawerContent is internally creating a top
Box for profile section to show profile image. ( I am showing this as an example: there is no real implementation for the user profile).
DrawerContent is also using
NavigationDrawerItem built-in composable from material3 to show
onClick of each menu exposing a lambda
onMenuClick passing in the
route to navigate to in its parent
Next we will see how to connect all of these pieces together, let’s see
MainNavigation code below.
One thing to note is that I am passing
drawerState reference in each Screen composable. It will be used to show
Menu icon inside the AppBar if
drawerState is provided. That’s because each screen is creating its own AppBar and passing
drawerState will do the job of showing
Menu icon and opening
Drawer when the user taps on it.
To see it in detail let’s take example of
ArticlesScreen and CustomAppBar.
drawerState is being passed from Screen composable to the
CustomAppBar composable and internally it shows
menu icon if it exists and opens
Drawer when the user taps on it.
This way each screen has to create its own
AppBar. You can also create
AppBar in main Navigation where
NavHost is being created and don’t pass drawerState down to screen and further to AppBar but in that approach it will get complicated particularly if each particular screen has some custom actions to show in
AppBar then one
AppBar for all
NavHost screens will get complicated.
Let’s see Pros and Cons of both cases.
Approach 1: Each NavHost screen creates its own AppBar
titleetc will be encapsulated within the screen where its showing.
MainNavigationwill not be responsible for individual title or other information inside AppBar which are specific to screen.
- Adding custom actions per screen on
AppBarwill be easy and encapsulated because each screen will add its own custom actions
drawerStatereference to pass down to the screens.
- Drawer opening/closing will be handled inside Custom
Approach 2: MainNavigation creates and manages AppBar for screens.
drawerStatewill not need to pass down to the individual screens composables
- Drawer opening/closing will be handled inside
AppBarinstance will be created for all screens which will be hard to maintain for each screen.
- Screen specific information like screen title etc will be exposed outside the individual module.
- If screens perform different actions via
AppBarthen managing those actions and icons per screen inside
MainNavigationwill get complex.
Let’s look into final outcome.
That’s it for now, in next story I will elaborate best practices in Navigation Compose and will modularise the code per screen/feature.
Remember to follow and 👏 if you liked it 🙂
- Mobile App Development (445)