You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android:如何在含BottomNavigationBar的Activity中添加单Toolbar的NavigationDrawer

Hey there! Let's tackle this problem step by step. You want to swap out those per-fragment Toolbars for a single, unified ActionBar in your MainActivity that plays nice with both BottomNavigationBar and NavigationDrawer. Here's a clear, actionable solution:

1. Redesign MainActivity's Layout

First, restructure your MainActivity layout to use a DrawerLayout as the root container. This will wrap your new shared Toolbar, BottomNavigationView, Fragment container, and the NavigationView for the drawer. Here's the layout code:

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <!-- Main content area -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <!-- Shared Toolbar (this becomes your ActionBar) -->
        <androidx.appcompat.widget.Toolbar
            android:id="@+id/main_toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:titleTextColor="@android:color/white"/>

        <!-- Fragment container -->
        <FrameLayout
            android:id="@+id/fragment_container"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"/>

        <!-- BottomNavigationBar -->
        <com.google.android.material.bottomnavigation.BottomNavigationView
            android:id="@+id/bottom_nav"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:menu="@menu/bottom_nav_menu"/>

    </LinearLayout>

    <!-- Navigation Drawer -->
    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:menu="@menu/drawer_menu"/>

</androidx.drawerlayout.widget.DrawerLayout>
2. Update Your App Theme

Keep using the NoActionBar theme (since we're using a custom Toolbar as the ActionBar). Make sure your theme in styles.xml looks something like this:

<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>
3. Wire Up MainActivity Code

Now, let's connect all the pieces in your MainActivity. We'll set the Toolbar as the support ActionBar, link it to the NavigationDrawer, handle BottomNavigation switches, and update the ActionBar title dynamically.

class MainActivity : AppCompatActivity() {

    private lateinit var drawerLayout: DrawerLayout
    private lateinit var appBarConfiguration: AppBarConfiguration

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Set up the shared Toolbar as the ActionBar
        val toolbar = findViewById<Toolbar>(R.id.main_toolbar)
        setSupportActionBar(toolbar)

        // Initialize DrawerLayout and NavigationView
        drawerLayout = findViewById(R.id.drawer_layout)
        val navView = findViewById<NavigationView>(R.id.nav_view)

        // Configure which destinations show the drawer icon
        appBarConfiguration = AppBarConfiguration(
            setOf(
                R.id.home_fragment, R.id.search_fragment, R.id.add_fragment, 
                R.id.notifications_fragment, R.id.profile_fragment
            ), drawerLayout
        )

        // Link the ActionBar to the DrawerLayout with a toggle button
        val toggle = ActionBarDrawerToggle(
            this, drawerLayout, toolbar,
            R.string.navigation_drawer_open, R.string.navigation_drawer_close
        )
        drawerLayout.addDrawerListener(toggle)
        toggle.syncState()

        // Handle NavigationView menu clicks (customize this as needed)
        navView.setNavigationItemSelectedListener { menuItem ->
            // Add your drawer menu logic here
            drawerLayout.closeDrawer(GravityCompat.START)
            true
        }

        // Handle BottomNavigation switches
        val bottomNav = findViewById<BottomNavigationView>(R.id.bottom_nav)
        bottomNav.setOnItemSelectedListener { item ->
            val fragment = when (item.itemId) {
                R.id.home_fragment -> HomeFragment()
                R.id.search_fragment -> SearchFragment()
                R.id.add_fragment -> AddFragment()
                R.id.notifications_fragment -> NotificationsFragment()
                R.id.profile_fragment -> ProfileFragment()
                else -> return@setOnItemSelectedListener false
            }

            // Replace the current fragment
            supportFragmentManager.beginTransaction()
                .replace(R.id.fragment_container, fragment)
                .commit()

            // Update ActionBar title (or let fragments handle this, see step 5)
            supportActionBar?.title = when (item.itemId) {
                R.id.home_fragment -> "Home"
                R.id.search_fragment -> "Search"
                R.id.add_fragment -> "Add"
                R.id.notifications_fragment -> "Notifications"
                R.id.profile_fragment -> "Profile"
                else -> ""
            }

            true
        }

        // Load the default fragment on first launch
        if (savedInstanceState == null) {
            bottomNav.selectedItemId = R.id.home_fragment
        }
    }

    // Close drawer when back button is pressed (if open)
    override fun onBackPressed() {
        if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
            drawerLayout.closeDrawer(GravityCompat.START)
        } else {
            super.onBackPressed()
        }
    }
}
4. Remove Per-Fragment Toolbars

Go into each of your 5 Fragment layouts and delete the Toolbar elements—we don't need them anymore, since we're using the shared ActionBar from MainActivity.

5. Optional: Let Fragments Control Their Own Titles

If you prefer to keep title logic inside each Fragment (instead of hardcoding in MainActivity), you can set the title directly in each Fragment's onViewCreated method:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    requireActivity().supportActionBar?.title = "Home" // Replace with your fragment's title
}

This keeps your code more decoupled—MainActivity only handles navigation, and Fragments manage their own display details.

Quick Troubleshooting Tips
  • Drawer icon not showing? Double-check that you've initialized ActionBarDrawerToggle and called toggle.syncState(), and that your AppBarConfiguration includes all your BottomNavigation destination IDs.
  • Title not updating? Make sure you're setting supportActionBar?.title either in MainActivity's BottomNavigation listener or in the Fragment's onViewCreated.
  • Drawer not sliding? Ensure your root layout is DrawerLayout, the NavigationView has layout_gravity="start", and the main content area doesn't have a gravity set.

内容的提问来源于stack exchange,提问作者Mahmoud Ayman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:39:59