Android Studio多Activity共用导航抽屉菜单的问题求助
解决Android导航抽屉基类布局复用问题
兄弟,我看了你遇到的几个问题,核心根源在于BaseActivity里重写的setContentView方法逻辑错误,把子类的布局加载到了NavigationView里面,而不是DrawerLayout的内容容器区域。咱们一步步来修正:
第一步:修正activity_base.xml的布局结构
首先你的activity_base.xml需要是标准的DrawerLayout结构,里面要包含两个核心部分:侧边的NavigationView,以及一个专门用来承载子类布局的容器(比如FrameLayout)。示例结构如下:
<?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/drawerLayout" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- 子类布局的容器,所有继承BaseActivity的页面布局都会加载到这里 --> <FrameLayout android:id="@+id/content_container" android:layout_width="match_parent" android:layout_height="match_parent"/> <!-- 侧边导航菜单 --> <com.google.android.material.navigation.NavigationView android:id="@+id/navigation_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" app:menu="@menu/your_nav_menu"/> <!-- 替换成你自己的菜单资源文件 --> </androidx.drawerlayout.widget.DrawerLayout>
第二步:修改BaseActivity的核心逻辑
原来的代码把子类布局错误地塞进了NavigationView里,这直接导致了布局混乱和点击无响应的问题。咱们调整setContentView方法,把内容加载到正确的容器中:
public class BaseActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { private DrawerLayout mDrawerLayout; private ActionBarDrawerToggle mToggle; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 先加载基类的DrawerLayout整体结构 super.setContentView(R.layout.activity_base); mDrawerLayout = findViewById(R.id.drawerLayout); mToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.string.Open, R.string.Close); mDrawerLayout.addDrawerListener(mToggle); mToggle.syncState(); getSupportActionBar().setDisplayHomeAsUpEnabled(true); NavigationView navigationView = findViewById(R.id.navigation_view); navigationView.setNavigationItemSelectedListener(this); } @Override public void setContentView(int layoutResID) { // 找到内容容器,把子类的布局加载进去 ViewGroup contentContainer = findViewById(R.id.content_container); getLayoutInflater().inflate(layoutResID, contentContainer, true); } @Override public boolean onOptionsItemSelected(MenuItem item) { if(mToggle.onOptionsItemSelected(item)){ return true; } return super.onOptionsItemSelected(item); } @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { int id = item.getItemId(); if(id == R.id.nav_Home) { startActivity(new Intent(this, MainActivity.class)); } else if(id == R.id.nav_Activity1) { startActivity(new Intent(this, Activity1.class)); } // 点击菜单选项后自动关闭抽屉,提升用户体验 mDrawerLayout.closeDrawer(GravityCompat.START); return true; } }
这里还要注意两个细节:
- 在
onCreate里先调用super.setContentView(R.layout.activity_base)加载基类的DrawerLayout结构,避免和重写的setContentView逻辑混淆 - 在
onNavigationItemSelected末尾加上关闭抽屉的代码,让交互更合理
第三步:简化MainActivity的代码
现在你的MainActivity只需要正常调用父类方法即可,不用手动做布局加载的操作:
public class MainActivity extends BaseActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } }
问题根源复盘
- 直接启动BaseActivity时布局为空:因为BaseActivity是作为基类设计的,本身没有加载业务布局,你应该启动继承它的子类Activity(比如MainActivity)
- MainActivity菜单图标无法点击:原来的布局结构错误导致ActionBarDrawerToggle无法正确绑定DrawerLayout,自然无法响应点击
- 手动加载布局导致主布局嵌入菜单:因为你把内容布局加到了NavigationView内部,相当于菜单里嵌套了主界面,显示必然异常
内容的提问来源于stack exchange,提问作者Zwax
相关产品推荐
相关产品推荐

