底部导航选中其他项时如何移除FloatingActionButton加载的Fragment
问题根源
你当前混用了Navigation组件导航和原生FragmentManager手动事务,NavController只管理自身navGraph中配置的页面跳转,你手动replace到nav_host_fragment里的PostFragment不属于NavController的管理范围,所以切换底部导航菜单项时,NavController不会自动移除这个手动添加的Fragment,才会出现页面重叠。
解决步骤
方案一(推荐):统一用Navigation组件管理所有页面跳转
- 先将PostFragment添加到导航图配置中,打开
res/navigation/mobile_navigation.xml,新增PostFragment的目的地配置,给它设置唯一id,比如R.id.post_fragment。如果你的底部导航原有菜单项已经对应PostFragment,直接用原有id即可。 - 修改FAB的点击逻辑,不要手动开启Fragment事务,改用NavController跳转:
// 先把navController提到layout方法内的全局作用域,方便后面调用 NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 替换为你导航图中PostFragment对应的id navController.navigate(R.id.post_fragment); } });
所有页面归NavController统一管理后,切换底部导航时会自动处理栈内页面,不会出现重叠问题,同时返回逻辑也不用额外适配。
方案二:不想调整导航配置,手动监听底部导航选中事件清理PostFragment
给BottomNavigationView添加自定义选中监听,每次切换菜单项时检测并移除手动添加的PostFragment:
navView.setOnItemSelectedListener(item -> { // 检测当前显示的是否是手动添加的PostFragment Fragment navHost = getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment); if (navHost != null) { Fragment currentFragment = navHost.getChildFragmentManager().getFragments().get(0); if (currentFragment instanceof PostFragment) { navHost.getChildFragmentManager().beginTransaction() .remove(currentFragment) .commit(); } } // 保留原有Navigation的跳转逻辑 NavigationUI.onNavDestinationSelected(item, navController); return true; });
注意:你当前代码调用了两次
setContentView,要确保NavController、FAB、底部导航的初始化都在setContentView(R.layout.activity_main)之后执行,避免空指针异常。
内容的提问来源于stack exchange,提问作者mayra
相关产品推荐
相关产品推荐

