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

已实现Toolbar背景色随AppBarLayout折叠变化,如何修改菜单项颜色?

嘿,我知道你已经搞定了AppBarLayout折叠时修改Toolbar背景色的功能,现在想让Toolbar上的菜单项颜色也跟着折叠状态同步变化对吧?这个需求很常见,咱们可以通过监听AppBarLayout的滚动偏移量,动态给菜单项图标着色来实现,下面给你两种实用的方案:

方案一:直接监听AppBarLayout偏移量(快速实现)

这个方法简单直接,适合单个页面使用。核心思路是计算AppBarLayout的折叠比例,根据比例切换或渐变菜单项颜色。

首先在你的Activity/Fragment里获取AppBarLayout和Toolbar实例,然后添加偏移监听:

// 假设你已经通过ViewBinding或findViewById拿到了实例
val appBarLayout = binding.appBarLayout
val toolbar = binding.toolbar

// 添加偏移变化监听
appBarLayout.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { _, verticalOffset ->
    // 计算折叠进度:verticalOffset的范围是0到 -appBarLayout.totalScrollRange
    val scrollRange = appBarLayout.totalScrollRange
    val collapseRatio = Math.abs(verticalOffset).toFloat() / scrollRange.toFloat()

    // 方式1:阈值切换(比如折叠超过50%时切换颜色)
    if (collapseRatio > 0.5f) {
        // 折叠到一半以上,设置菜单项为深色
        setToolbarMenuColor(toolbar, R.color.dark_primary)
    } else {
        // 展开状态,设置菜单项为浅色
        setToolbarMenuColor(toolbar, R.color.light_primary)
    }

    // 方式2:渐变过渡(更丝滑的效果)
    val evaluator = ArgbEvaluator()
    val currentColor = evaluator.evaluate(
        collapseRatio,
        ContextCompat.getColor(this, R.color.light_primary),
        ContextCompat.getColor(this, R.color.dark_primary)
    ) as Int
    setToolbarMenuColor(toolbar, currentColor)
})

// 封装的设置菜单项颜色的工具方法
private fun setToolbarMenuColor(toolbar: Toolbar, colorRes: Int) {
    val color = ContextCompat.getColor(this, colorRes)
    // 设置导航图标颜色
    toolbar.navigationIcon?.setTint(color)
    // 遍历所有菜单项设置颜色
    toolbar.menu.forEach { menuItem ->
        menuItem.icon?.setTint(color)
    }
}

注意事项:

  • 如果你的Toolbar菜单是动态加载的(比如在onCreateOptionsMenu里添加),记得在菜单加载完成后同步调用setToolbarMenuColor,避免初始颜色不一致。
  • 页面销毁时记得移除监听,防止内存泄漏:
override fun onDestroy() {
    super.onDestroy()
    appBarLayout.removeOnOffsetChangedListener(this)
}
方案二:自定义Behavior(复用性更高)

如果你的App多个页面都需要这个效果,建议用CoordinatorLayout的Behavior来实现,代码更解耦,复用性强。

首先自定义一个Behavior类:

class ToolbarMenuColorBehavior : AppBarLayout.ScrollingViewBehavior() {
    private var toolbar: Toolbar? = null
    private var lightColor: Int = 0
    private var darkColor: Int = 0
    private val offsetListener = AppBarLayout.OnOffsetChangedListener { appBarLayout, verticalOffset ->
        val scrollRange = appBarLayout.totalScrollRange
        val collapseRatio = Math.abs(verticalOffset).toFloat() / scrollRange.toFloat()
        
        // 用ArgbEvaluator实现颜色渐变
        val evaluator = ArgbEvaluator()
        val currentColor = evaluator.evaluate(collapseRatio, lightColor, darkColor) as Int
        
        toolbar?.run {
            navigationIcon?.setTint(currentColor)
            menu.forEach { it.icon?.setTint(currentColor) }
        }
    }

    override fun layoutDependsOn(parent: CoordinatorLayout, child: View, dependency: View): Boolean {
        if (dependency is AppBarLayout) {
            toolbar = parent.findViewById(R.id.toolbar)
            lightColor = ContextCompat.getColor(parent.context, R.color.light_primary)
            darkColor = ContextCompat.getColor(parent.context, R.color.dark_primary)
            dependency.addOnOffsetChangedListener(offsetListener)
            return true
        }
        return super.layoutDependsOn(parent, child, dependency)
    }

    override fun onDetachedFromLayoutParams() {
        super.onDetachedFromLayoutParams()
        // 移除监听,防止内存泄漏
        (dependency as? AppBarLayout)?.removeOnOffsetChangedListener(offsetListener)
    }
}

然后在布局文件中,给和AppBarLayout联动的滚动视图(比如NestedScrollView)设置这个Behavior:

<androidx.core.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior=".ToolbarMenuColorBehavior">

    <!-- 你的页面内容 -->
</androidx.core.widget.NestedScrollView>

额外提示:

  • 确保你的菜单项图标是矢量图(VectorDrawable),如果用普通PNG图,着色效果可能不理想。如果必须用PNG,可以在Drawable的xml中设置android:tintMode="src_in"来优化着色效果。
  • 如果需要调整颜色切换的阈值,只需要修改collapseRatio的判断条件(比如改成0.3f就是折叠30%时切换)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:52:06