Android Studio多Activity共享单个Navigation Drawer实现求助
问题原因及解决方案
你的核心问题有两个:
- MainActivity覆盖了BaseActivity的布局:子类调用
setContentView(R.layout.activity_main)会完全替换BaseActivity中加载的抽屉布局,导致侧边菜单根本没被渲染。 - 缺少抽屉打开的触发逻辑: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
相关产品推荐
相关产品推荐

