Android Drawer切换Fragment后无法关闭的问题排查及代码咨询
问题解决:Drawer点击选项后不自动关闭
核心问题分析
你给出的两行关闭Drawer的代码本身是正确的:
DrawerLayout drawer = binding.drawerLayout; drawer.closeDrawer(GravityCompat.START);
但问题出在代码执行时机——在你的onNavigationItemSelected方法中,每个菜单分支都直接return true,导致关闭Drawer的代码根本没机会执行。只有当点击的菜单项不在你判断的三个ID范围内时,才会走到关闭逻辑,这就是为什么只有主页可能触发关闭(NavigationUI默认逻辑兜底),其他选项无法关闭Drawer。
快速修复方案
调整onNavigationItemSelected的代码结构,将关闭Drawer的逻辑移到所有分支判断之后,确保无论点击哪个选项都会执行关闭操作:
@Override public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) { Log.d("edo","mphka1"); int id = menuItem.getItemId(); if (id == R.id.nav_home) { setFragement(new CategoryFragment()); } else if (id == R.id.nav_leaderboard) { setFragement(new LeaderBoardFragment()); } else if (id == R.id.nav_account) { setFragement(new AccountFragment()); } // 统一在最后关闭Drawer DrawerLayout drawer = binding.drawerLayout; drawer.closeDrawer(GravityCompat.START); return true; }
优化建议:统一使用Navigation组件
你的代码同时混合了手动FragmentTransaction和Navigation组件两种导航方式,不仅冗余,还容易引发冲突(比如Drawer关闭逻辑不一致)。建议完全基于Navigation组件来管理导航,这样可以自动处理Drawer关闭:
- 修改content_main布局:移除冗余的
FrameLayout,保留NavHostFragment作为唯一的Fragment容器:
<?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" android:background="@drawable/main_background" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:showIn="@layout/app_bar_main"> <fragment android:id="@+id/nav_host_fragment_content_main" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="match_parent" android:layout_height="match_parent" app:defaultNavHost="true" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:navGraph="@navigation/mobile_navigation" /> <com.google.android.material.bottomnavigation.BottomNavigationView android:id="@+id/bottom_nav_bar" android:layout_width="0dp" android:layout_height="wrap_content" android:background="?android:attr/windowBackground" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:menu="@menu/bottom_menu"> </com.google.android.material.bottomnavigation.BottomNavigationView> </androidx.constraintlayout.widget.ConstraintLayout>
- 简化MainActivity代码:
- 移除自定义的
setFragment方法和BottomNavigationView的手动监听 - 使用NavigationUI绑定BottomNavigationView,自动处理导航和Drawer关闭:
- 移除自定义的
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ActivityMainBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); setSupportActionBar(binding.appBarMain.toolbar); bottomNavigationView = findViewById(R.id.bottom_nav_bar); DrawerLayout drawer = binding.drawerLayout; NavigationView navigationView = binding.navView; mAppBarConfiguration = new AppBarConfiguration.Builder( R.id.nav_home, R.id.nav_leaderboard, R.id.nav_account) .setDrawerLayout(drawer) .build(); drawerProfileName = navigationView.getHeaderView(0).findViewById(R.id.nav_drawer_name); drawerProfileText = navigationView.getHeaderView(0).findViewById(R.id.nav_drawer_text_img); String name = DbQuery.myProfile.getName(); drawerProfileName.setText(name); drawerProfileText.setText(name.toUpperCase(Locale.ROOT).substring(0,1)); NavController navController = Navigation.findNavController(this, nav_host_fragment_content_main); NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration); // 绑定Drawer菜单和BottomNavigationView,自动处理导航+Drawer关闭 NavigationUI.setupWithNavController(navigationView, navController); NavigationUI.setupWithNavController(bottomNavigationView, navController); // 移除自定义的navigationView.setNavigationItemSelectedListener(this); }
这样配置后,点击Drawer或BottomNavigationView的菜单项时,NavigationUI会自动切换Fragment并关闭Drawer,无需手动编写关闭代码,同时避免了两种导航方式的冲突。
内容的提问来源于stack exchange,提问作者Θεοφανης Γιαννακοπου
相关产品推荐
相关产品推荐

