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

Android如何实现内嵌Navigation Drawer的BottomNavigationView

实现方案

你要实现的是导航抽屉仅在内容区域展示、不覆盖底部导航栏的效果,只需调整布局结构、新增底部触发按钮、添加点击逻辑即可,具体修改如下:

1. 修改activity_main.xml布局结构

原布局中DrawerLayout作为根布局会导致抽屉全屏展示,调整为ConstraintLayout作为根布局,将DrawerLayout限制在底部导航栏上方的内容区域:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <!-- 把DrawerLayout放到内容区域,约束在底部导航上方 -->
    <androidx.drawerlayout.widget.DrawerLayout
        android:id="@+id/main_drawer"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@id/main_bottom_nav">

        <!-- 内容区域 -->
        <fragment
            android:id="@+id/main_fragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:name="androidx.navigation.fragment.NavHostFragment"
            app:defaultNavHost="true"
            app:navGraph="@navigation/mainnav_graph"/>

        <!-- 导航抽屉 -->
        <com.google.android.material.navigation.NavigationView
            android:id="@+id/main_sidebar"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            app:menu="@menu/drawer_menu"/>

    </androidx.drawerlayout.widget.DrawerLayout>

    <!-- 底部导航栏固定在最底部 -->
    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/main_bottom_nav"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:menu="@menu/bottom_nav_menu"/>

</androidx.constraintlayout.widget.ConstraintLayout>

2. 修改bottom_nav_menu.xml新增更多触发按钮

在底部导航菜单中添加用于打开抽屉的更多按钮:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/navigation_home"
        android:icon="@drawable/ic_home_black_24dp"
        android:title="@string/title_home" />
    <item
        android:id="@+id/navigation_friends"
        android:icon="@drawable/ic_home_black_24dp"
        android:title="@string/title_friends" />
    <item
        android:id="@+id/navigation_order"
        android:icon="@drawable/ic_dashboard_black_24dp"
        android:title="@string/title_order" />
    <!-- 新增更多按钮,用于触发抽屉 -->
    <item
        android:id="@+id/navigation_more"
        android:icon="@drawable/ic_menu_black_24dp"
        android:title="更多" />
</menu>

3. 修改MainActivity.java添加底部更多按钮的点击逻辑

在setupNavigation方法后添加底部导航的点击拦截,点击更多按钮时直接打开抽屉,不触发导航跳转:

private void setupNavigation() {
    Log.i(TAG, "setupNavigation: ");
    navController = Navigation.findNavController(this, R.id.main_fragment);
    appBarConfiguration =
            new AppBarConfiguration.Builder(R.id.navigation_friends,R.id.navigation_order,R.id.navigation_home,R.id.navigation_groups,R.id.navigation_settings,R.id.navigation_profile,R.id.navigation_all_activity)
                    .setDrawerLayout(drawerLayout)
                    .build();

    NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
    NavigationUI.setupWithNavController(navigationView, navController);
    NavigationUI.setupWithNavController(bottomNavigationView, navController);

    // 新增:拦截底部导航点击事件,处理更多按钮逻辑
    bottomNavigationView.setOnItemSelectedListener(item -> {
        if (item.getItemId() == R.id.navigation_more) {
            // 点击更多按钮直接打开抽屉
            if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
                drawerLayout.closeDrawer(GravityCompat.START);
            } else {
                drawerLayout.openDrawer(GravityCompat.START);
            }
            return true;
        }
        // 其他按钮走默认导航逻辑
        return NavigationUI.onNavDestinationSelected(item, navController);
    });
}

其他说明

现有逻辑中的onBackPressed、onSupportNavigateUp方法无需修改,可正常运行;如果不需要顶部ActionBar显示抽屉按钮,可以移除setupActionBarWithNavController相关代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 06:06:03