按返回键切换Fragment时BottomNavigationView菜单项未选中问题求解
问题根因
- 调用
addToBackStack()时传入了null,导致回退栈条目BackStackEntry的name字段为空,后续拿name和Fragment类名对比的逻辑完全不触发,自然不会同步选中导航项 - 当回退栈只剩下1个条目时按返回键,回退栈计数变为0,直接取
backStackEntryCount - 1会出现索引越界崩溃 - 首次加载的FeedFragment对应回退栈条目同样没有设置名称,初始状态匹配逻辑也不生效
修复方案
第一步 修改loadFragments方法,给回退栈条目设置名称
将Fragment类名作为标识传入addToBackStack:
fun loadFragments(fragment:Fragment?):Boolean{ if(fragment != null){ supportFragmentManager.beginTransaction() .replace(R.id.parentFrame,fragment) // 传入Fragment类名作为回退栈条目的名称 .addToBackStack(fragment::class.java.name) .commit() } return true }
第二步 修改onBackStackChanged方法,增加边界判断
override fun onBackStackChanged() { val count = supportFragmentManager.backStackEntryCount // 回退栈为空时直接关闭页面,可根据业务需求调整逻辑 if (count == 0) { finish() return } val bse = supportFragmentManager.getBackStackEntryAt(count - 1) when(bse.name) { FeedFragment::class.java.name -> bottomNavigationView.menu.getItem(0).isChecked = true VideosFragment::class.java.name -> bottomNavigationView.menu.getItem(1).isChecked = true ExploreFragment::class.java.name -> bottomNavigationView.menu.getItem(2).isChecked = true } }
可选优化:复用Fragment实例
现有逻辑每次点击导航项都会新建Fragment实例,会产生不必要的内存开销,可提前初始化实例复用:
// 类成员变量提前初始化三个Fragment private val feedFragment = FeedFragment() private val videosFragment = VideosFragment() private val exploreFragment = ExploreFragment() override fun onNavigationItemSelected(item: MenuItem): Boolean { val fragment = when(item.itemId){ R.id.feedFragment -> feedFragment R.id.videosFragment -> videosFragment R.id.exploreFragment -> exploreFragment else -> null } return loadFragments(fragment) }
内容的提问来源于stack exchange,提问作者Aadish Sharma
相关产品推荐
相关产品推荐

