使用Jetpack Navigation Library时自定义Toolbar导航图标问题
因为NavigationUI会在导航过程中自动覆盖导航图标,直接调用toolbar.setNavigationIcon()或supportActionBar.setIcon()确实不会生效,下面给你几个靠谱的解决办法:
方案一:监听导航事件替换图标
在调用setupActionBarWithNavController之后,给NavController添加导航监听,每次导航完成后手动替换图标——毕竟NavigationUI刚设置完图标,我们紧接着覆盖它就行:
val navController = findNavController(R.id.nav_host_fragment) setupActionBarWithNavController(navController) // 监听导航切换事件 navController.addOnNavigatedListener { _, destination -> // 根据当前目的地判断用汉堡还是返回图标 val customIcon = if (destination.id == R.id.home_fragment) { ContextCompat.getDrawable(this, R.drawable.my_custom_hamburger) } else { ContextCompat.getDrawable(this, R.drawable.my_custom_back_arrow) } // 替换系统设置的图标 supportActionBar?.setHomeAsUpIndicator(customIcon) }
这个方法简单直接,适合大多数场景,能保证每个页面的导航图标都是你自定义的样式。
方案二:自定义DrawerToggle(搭配DrawerLayout时用)
如果你的项目用了DrawerLayout,可以绕过NavigationUI的默认Toggle,自己创建ActionBarDrawerToggle并设置自定义图标:
val drawerLayout = findViewById<DrawerLayout>(R.id.drawer_layout) val navController = findNavController(R.id.nav_host_fragment) val toolbar = findViewById<Toolbar>(R.id.toolbar) // 自定义DrawerToggle,替换默认汉堡图标 val customToggle = object : ActionBarDrawerToggle( this, drawerLayout, toolbar, R.string.drawer_open, R.string.drawer_close ) {} // 设置自定义汉堡图标 customToggle.setHomeAsUpIndicator(R.drawable.my_custom_hamburger) drawerLayout.addDrawerListener(customToggle) customToggle.syncState() // 处理导航返回逻辑 override fun onSupportNavigateUp(): Boolean { val navController = findNavController(R.id.nav_host_fragment) return navController.navigateUp() || super.onSupportNavigateUp() }
这种方式完全接管了抽屉的图标控制,同时不影响导航和抽屉的联动逻辑。
方案三:重写NavigationUI的逻辑(进阶)
如果需要全局统一替换所有页面的导航图标,可以复制NavigationUI中设置图标的源码,修改成自己的逻辑,然后用自定义方法代替系统的setupActionBarWithNavController:
fun setupCustomActionBarWithNavController(activity: AppCompatActivity, navController: NavController) { val actionBar = activity.supportActionBar ?: return navController.addOnNavigatedListener { _, _ -> val shouldShowUp = NavigationUI.shouldShowUp(navController) // 自定义图标 val upIndicator = if (shouldShowUp) { ContextCompat.getDrawable(activity, R.drawable.my_custom_back) } else { ContextCompat.getDrawable(activity, R.drawable.my_custom_hamburger) } actionBar.setHomeAsUpIndicator(upIndicator) actionBar.setDisplayHomeAsUpEnabled(shouldShowUp) } }
之后在Activity里调用这个自定义方法就行,不用再调用系统的setupActionBarWithNavController。
内容的提问来源于stack exchange,提问作者Ishaan Garg
相关产品推荐
相关产品推荐

