Android Development
Navigation Drawer
User Interface
Multiple Activities
Code Reusability

Same Navigation Drawer in different Activities

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

When an Android app still uses multiple activities, keeping one consistent navigation drawer across screens prevents duplicated code and navigation bugs. Without a shared pattern, menu handling, checked states, and toolbar behavior drift over time. A robust solution centralizes drawer setup in reusable infrastructure and keeps each activity focused on screen content.

Use One Shared Drawer Shell Layout

Create one layout that contains DrawerLayout, NavigationView, and a content container. Each activity then inflates its own content view into that container.

xml
1<!-- res/layout/activity_drawer_shell.xml -->
2<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
3    xmlns:app="http://schemas.android.com/apk/res-auto"
4    android:id="@+id/drawerLayout"
5    android:layout_width="match_parent"
6    android:layout_height="match_parent">
7
8    <LinearLayout
9        android:layout_width="match_parent"
10        android:layout_height="match_parent"
11        android:orientation="vertical">
12
13        <com.google.android.material.appbar.MaterialToolbar
14            android:id="@+id/toolbar"
15            android:layout_width="match_parent"
16            android:layout_height="wrap_content"/>
17
18        <FrameLayout
19            android:id="@+id/contentContainer"
20            android:layout_width="match_parent"
21            android:layout_height="match_parent"/>
22    </LinearLayout>
23
24    <com.google.android.material.navigation.NavigationView
25        android:id="@+id/navigationView"
26        android:layout_width="wrap_content"
27        android:layout_height="match_parent"
28        android:layout_gravity="start"
29        app:menu="@menu/main_drawer_menu"/>
30</androidx.drawerlayout.widget.DrawerLayout>

This guarantees visual consistency and keeps menu IDs stable.

Centralize Logic in a Base Activity

A base class should own drawer wiring, toolbar toggle, and menu routing.

kotlin
1abstract class BaseDrawerActivity : AppCompatActivity() {
2    protected abstract val contentLayoutRes: Int
3    protected abstract val selectedItemId: Int
4
5    private lateinit var drawerLayout: DrawerLayout
6    private lateinit var navigationView: NavigationView
7
8    override fun onCreate(savedInstanceState: Bundle?) {
9        super.onCreate(savedInstanceState)
10        setContentView(R.layout.activity_drawer_shell)
11
12        drawerLayout = findViewById(R.id.drawerLayout)
13        navigationView = findViewById(R.id.navigationView)
14
15        layoutInflater.inflate(contentLayoutRes, findViewById(R.id.contentContainer), true)
16        setupToolbarAndDrawer()
17        setupNavigation()
18    }
19
20    private fun setupToolbarAndDrawer() {
21        val toolbar = findViewById<MaterialToolbar>(R.id.toolbar)
22        setSupportActionBar(toolbar)
23
24        val toggle = ActionBarDrawerToggle(
25            this, drawerLayout, toolbar,
26            R.string.drawer_open, R.string.drawer_close
27        )
28        drawerLayout.addDrawerListener(toggle)
29        toggle.syncState()
30    }
31
32    private fun setupNavigation() {
33        navigationView.setCheckedItem(selectedItemId)
34        navigationView.setNavigationItemSelectedListener { item ->
35            navigate(item.itemId)
36            drawerLayout.closeDrawers()
37            true
38        }
39    }
40
41    private fun navigate(itemId: Int) {
42        val target = when (itemId) {
43            R.id.nav_home -> HomeActivity::class.java
44            R.id.nav_profile -> ProfileActivity::class.java
45            R.id.nav_settings -> SettingsActivity::class.java
46            else -> return
47        }
48
49        if (target != this::class.java) {
50            startActivity(Intent(this, target))
51            finish()
52        }
53    }
54}

Each child activity only declares content and active menu item.

Keep Back Stack and State Predictable

Drawer navigation should usually behave like top-level navigation. Avoid stacking repeated activity instances.

Recommended behavior:

  • if target screen is already active, do nothing,
  • if switching top-level screens, optionally call finish to keep stack clean,
  • preserve current drawer selection after configuration changes.

Also save and restore key UI state in each activity as needed, especially when forms exist inside content screens.

Use one canonical menu file shared by all activities.

xml
1<!-- res/menu/main_drawer_menu.xml -->
2<menu xmlns:android="http://schemas.android.com/apk/res/android">
3    <item android:id="@+id/nav_home" android:title="Home"/>
4    <item android:id="@+id/nav_profile" android:title="Profile"/>
5    <item android:id="@+id/nav_settings" android:title="Settings"/>
6</menu>

Do not create per-activity variants unless product requirements demand role-based visibility. If visibility changes by role, keep IDs identical and toggle visibility in one shared function.

Testing Recommendations

High-value tests for this pattern:

  • selecting each menu item routes to expected activity,
  • current item is highlighted correctly,
  • repeated tap on current destination does not duplicate screen,
  • drawer opens and closes with toolbar toggle.

UI tests with Espresso can validate route behavior. Unit tests can validate route mapping logic in pure Kotlin helpers.

Migration Path Toward Single-Activity Navigation

If your roadmap includes Jetpack Navigation with fragments, this base-activity drawer design still helps. You can keep menu definitions and route contracts stable while gradually replacing activity targets with navigation actions.

A staged migration avoids big-bang rewrites:

  • keep existing activity routes working,
  • introduce fragment destinations for new screens,
  • move one menu item at a time to NavController handling.

This preserves user experience consistency while reducing architecture risk.

Common Pitfalls

  • Copying drawer setup into every activity and drifting behavior.
  • Reusing menu labels but changing item IDs across screens.
  • Launching same activity repeatedly and polluting back stack.
  • Updating toolbar settings in child classes inconsistently.
  • Forgetting to synchronize drawer toggle after setup.

Summary

  • Use one drawer shell layout and one shared menu definition.
  • Centralize drawer setup and routing in a base activity.
  • Keep child activities focused on content and selected menu ID.
  • Enforce predictable top-level navigation and back stack behavior.
  • Test routing, highlighting, and duplicate-launch prevention explicitly.

Course illustration
Course illustration

All Rights Reserved.