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

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关闭:

  1. 修改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>
  1. 简化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,提问作者Θεοφανης Γιαννακοπου

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 05:25:05