You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Navigation搭配Material Toolbar导航时工具栏渲染闪烁问题咨询

问题原因

  1. 版本缺陷:你使用的Jetpack Navigation 2.3.5版本存在Toolbar配置与导航转场不同步的已知问题,setupWithNavController的执行时机晚于转场动画的触发时机,导致视觉上先出现默认配置再更新为自定义配置。
  2. 共用Toolbar的状态复用问题:如果你的MaterialToolbar放在Activity布局中,由所有Fragment共用,导航时Navigation会优先读取导航图中目的地的label属性,先给Toolbar设置默认标题、系统返回图标,等当前Fragment的onViewCreated执行自定义配置时才覆盖原有属性,两者的时间差就会产生闪烁。
  3. 样式未全局适配:Navigation自动设置的标题会沿用Toolbar的默认样式,如果你没有在主题中统一配置Toolbar的标题字号、颜色、导航图标样式,就会出现初始样式不符合预期的问题。

解决方案

方案1:升级Navigation版本(最优先)

直接将Navigation依赖升级到2.4.0及以上版本,官方在该版本中修复了大量Navigation UI与Toolbar的同步缺陷,绝大多数同类闪烁问题会直接修复。

方案2:Fragment独立管理Toolbar

不要共用Activity的Toolbar,将Toolbar放到每个Fragment的私有布局中,每个Fragment仅管理自己布局内的Toolbar:

  • 导航时新Fragment的Toolbar会跟随自身视图一起渲染,不会复用前一个页面的Toolbar状态
  • 避免了跨页面的Toolbar属性冲突,从根源上消除闪烁。

方案3:提前在Activity中监听导航变更配置Toolbar

如果必须共用Activity的Toolbar,不要在每个Fragment的onViewCreated中配置Toolbar,改为在Activity中注册OnDestinationChangedListener,导航触发时就直接设置对应页面的Toolbar属性:

navController.addOnDestinationChangedListener { _, destination, _ ->
    when(destination.id) {
        R.id.screen_c -> {
            toolbar.title = "SCREEN C"
            toolbar.setNavigationIcon(R.drawable.custom_back_c)
            toolbar.inflateMenu(R.menu.menu_c)
        }
        R.id.screen_d -> {
            toolbar.title = "SCREEN D"
            toolbar.setNavigationIcon(R.drawable.custom_back_d)
            toolbar.menu.clear()
        }
        // 其他页面配置
    }
}

该方案保证导航触发时Toolbar直接加载正确配置,没有二次修改的时间差。

方案4:禁用自动配置,手动控制Toolbar属性

如果要保留原有调用逻辑,调用setupWithNavController后立即手动覆盖Toolbar属性,避免默认配置残留:

val navController = NavHostFragment.findNavController(fragment)
val appBarConfiguration = AppBarConfiguration(navController.graph)
setupWithNavController(navController, appBarConfiguration)
// 手动覆盖属性
toolbar.apply {
    title = "当前页面标题"
    setTitleTextColor(ContextCompat.getColor(context, R.color.title_color))
    setTitleTextSize(TypedValue.COMPLEX_UNIT_SP, 16f)
    setNavigationIcon(R.drawable.custom_back_icon)
    // 控制菜单显隐
    menu.clear()
    if (需要显示菜单) inflateMenu(R.menu.current_menu)
}

同时在主题中统一配置MaterialToolbar的默认样式,避免初始样式异常:

<style name="AppTheme.Toolbar" parent="Widget.MaterialComponents.Toolbar">
    <item name="titleTextColor">@color/toolbar_title</item>
    <item name="titleTextAppearance">@style/ToolbarTitleText</item>
    <item name="navigationIcon">@drawable/ic_default_back</item>
</style>

内容的提问来源于stack exchange,提问作者Sarbyn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 08:36:02