Android Studio导航模板实现Navigation Drawer退出项且不影响Fragment切换
问题根因
NavigationUI.setupWithNavController()方法会自动给NavigationView设置默认的菜单项选中监听器,负责匹配菜单项ID和导航目的地ID完成Fragment切换。你手动调用setNavigationItemSelectedListener()会直接覆盖这个默认监听器,原有导航逻辑自然失效。
解决方法
你只需要在自定义的监听器里优先处理退出逻辑,其余菜单项继续交给NavigationUI的默认方法处理即可:
- 先确认你退出菜单项的ID,示例中假设为
R.id.nav_exit,替换为你实际布局中定义的ID - 在原有
setupWithNavController代码后添加自定义监听器,完整修改后的代码如下:
public class MainActivity extends AppCompatActivity { private AppBarConfiguration mAppBarConfiguration; private ActivityMainBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ActivityMainBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); setSupportActionBar(binding.appBarMain.toolbar); binding.appBarMain.fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) .setAction("Action", null).show(); } }); DrawerLayout drawer = binding.drawerLayout; NavigationView navigationView = binding.navView; // 这里不需要加退出菜单项的ID,退出不属于导航目的地 mAppBarConfiguration = new AppBarConfiguration.Builder( R.id.nav_home, R.id.nav_setting) .setDrawerLayout(drawer) .build(); NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main); NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration); // 原有设置导航的代码保留 NavigationUI.setupWithNavController(navigationView, navController); // 新增自定义菜单项选中监听 navigationView.setNavigationItemSelectedListener(item -> { int id = item.getItemId(); // 处理退出逻辑 if (id == R.id.nav_exit) { finish(); drawer.closeDrawers(); return true; } // 其他菜单项交给默认导航逻辑处理 boolean navHandled = NavigationUI.onNavDestinationSelected(item, navController); if (navHandled) { drawer.closeDrawers(); } return navHandled; }); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onSupportNavigateUp() { NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main); return NavigationUI.navigateUp(navController, mAppBarConfiguration) || super.onSupportNavigateUp(); } }
注意事项
- 不要把退出菜单项的ID加到
AppBarConfiguration的构造参数里,它不属于顶部导航目的地 - 处理完退出逻辑返回
true表示该事件已被消费,不需要后续处理 - 非退出的菜单项调用
NavigationUI.onNavDestinationSelected()复用原有导航逻辑,保证原来的Fragment切换功能正常
内容的提问来源于stack exchange,提问作者Android Lover Boy
相关产品推荐
相关产品推荐

