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

Android Studio多Activity共享单个Navigation Drawer实现求助

问题原因及解决方案

你的核心问题有两个:

  1. MainActivity覆盖了BaseActivity的布局:子类调用setContentView(R.layout.activity_main)会完全替换BaseActivity中加载的抽屉布局,导致侧边菜单根本没被渲染。
  2. 缺少抽屉打开的触发逻辑:BaseActivity没有配置Toolbar的汉堡按钮点击事件,无法唤起侧边菜单。

修正步骤

1. 重构BaseActivity

添加抽屉开关逻辑,同时提供方法让子类将布局嵌入到抽屉的主内容区域:

public class BaseActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
    public ActivityBaseBinding binding;
    private DrawerLayout drawerLayout;
    private ActionBarDrawerToggle toggle;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityBaseBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        // 初始化DrawerLayout和NavigationView
        drawerLayout = binding.drawerLayout;
        NavigationView navigationView = binding.navView;
        navigationView.setNavigationItemSelectedListener(this);

        // 配置Toolbar的汉堡按钮
        Toolbar toolbar = binding.appBarBase.toolbar; // 假设app_bar_base布局里有id为toolbar的Toolbar
        setSupportActionBar(toolbar);
        toggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawerLayout.addDrawerListener(toggle);
        toggle.syncState();
    }

    // 让子类调用此方法加载自身布局到主内容区域
    protected void setContentViewToFrame(int layoutResId) {
        LayoutInflater inflater = getLayoutInflater();
        inflater.inflate(layoutResId, binding.contentFrame, true);
    }

    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.nav_home) {
            Intent intent = new Intent(this, MainActivity.class);
            startActivity(intent);
        }
        // 点击菜单项后关闭抽屉
        drawerLayout.closeDrawer(GravityCompat.START);
        return true;
    }

    @Override
    public void onBackPressed() {
        // 返回键关闭抽屉
        if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
            drawerLayout.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }
    }
}

2. 修改MainActivity

不再直接调用setContentView,而是使用BaseActivity提供的方法嵌入布局:

public class MainActivity extends BaseActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 把自身布局加载到BaseActivity的content_frame中
        setContentViewToFrame(R.layout.activity_main);
    }
}

3. 检查布局结构

确保activity_base.xml(对应ActivityBaseBinding)的层级正确,主内容区域的FrameLayout是DrawerLayout的第一个子View:

<androidx.drawerlayout.widget.DrawerLayout 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:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <!-- 主内容容器:子类布局会加载到这里 -->
    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <!-- 包含Toolbar的布局 -->
        <include
            android:id="@+id/app_bar_base"
            layout="@layout/app_bar_base"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </FrameLayout>

    <!-- 侧边导航栏 -->
    <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"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_base"
        app:menu="@menu/activity_base_drawer" />

</androidx.drawerlayout.widget.DrawerLayout>

补充说明

  • 确保app_bar_base.xml里有一个id为toolbar的Toolbar组件,否则BaseActivity中获取Toolbar会报错。
  • 所有继承BaseActivity的子类,都只需调用setContentViewToFrame加载自身布局,就能自动拥有侧边菜单功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 21:17:36