使用Android Navigation UI移除BottomNavigationView导航的ActionBar返回按钮
我完全懂你遇到的糟心事——用BottomNavigationView切换三个顶级Fragment时,ActionBar莫名其妙冒出来返回按钮,试了手动加NavOptions导航也没效果对吧?这其实是因为NavController默认会把所有导航操作都塞进返回栈,但咱们底部导航对应的Fragment都是顶级目的地,根本不该出现在返回栈里。
下面给你两种简单直接的解决办法:
方法一:代码中指定顶级目的地集合
直接在setupActionBarWithNavController时,把底部导航对应的三个Fragment ID传入集合,明确告诉NavController这些是顶级页面,切换到它们时别显示返回按钮:
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main_activity) setSupportActionBar(toolbar) val navController = navHostFragment.findNavController() // 替换成你自己的三个Fragment ID val topLevelDestinations = setOf( R.id.homeFragment, R.id.profileFragment, R.id.thirdFragment ) setupActionBarWithNavController(this, navController, topLevelDestinations) setupWithNavController(bottomNav, navController) } override fun onSupportNavigateUp(): Boolean = findNavController(navHostFragment).navigateUp() }
这样配置后,点击底部导航切换页面时,ActionBar会自动隐藏返回按钮;只有从这些顶级页面跳转到更深层级的页面时,才会正常显示返回按钮。
方法二:导航图XML中标记顶级目的地
如果你更习惯用XML配置,打开你的导航图文件(一般在res/navigation/nav_graph.xml),给每个底部导航对应的Fragment添加app:topLevelDestination="true"属性:
<navigation xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/nav_graph" app:startDestination="@id/homeFragment"> <fragment android:id="@+id/homeFragment" android:name="com.yourpackage.HomeFragment" android:label="首页" app:topLevelDestination="true"/> <fragment android:id="@+id/profileFragment" android:name="com.yourpackage.ProfileFragment" android:label="个人资料" app:topLevelDestination="true"/> <fragment android:id="@+id/thirdFragment" android:name="com.yourpackage.ThirdFragment" android:label="第三个页面" app:topLevelDestination="true"/> </navigation>
保存后重新运行应用,底部导航切换时就不会再出现多余的返回按钮了。
为啥之前的方法没用?
你之前尝试监听BottomNavigationView选择事件手动导航,大概率是没从根源上处理返回栈问题——普通的navigate()方法哪怕加了NavOptions,也可能没彻底清除不必要的栈条目。而上面两种方法是直接告诉NavController哪些是顶级页面,从根本上避免了这些页面被加入返回栈,自然就不会触发返回按钮的显示了。
内容的提问来源于stack exchange,提问作者jeffmcnd

