Android使用带Indicator的ViewPager时如何让状态栏背景跟随ViewPager同步变化?
实现方案
核心逻辑
监听ViewPager的滑动状态变化,根据当前滑动位置计算对应的状态栏颜色,同步赋值给Activity Window的状态栏属性即可,滑动过程中可通过ArgbEvaluator实现颜色的平滑过渡效果。
具体实现步骤
1. 前置准备
提前按页面顺序定义好每个页面对应的状态栏颜色数组:
private val pageStatusBarColors = intArrayOf( Color.parseColor("#FF4444"), // 第1页对应状态栏色值 Color.parseColor("#33B5E5"), // 第2页对应状态栏色值 Color.parseColor("#99CC00") // 第3页对应状态栏色值 )
如果你的页面背景是图片/渐变,可以用Android官方的Palette库提取页面背景的主色作为对应页面的状态栏颜色。
2. 给ViewPager添加滑动监听器
针对ViewPager
viewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { // 用于计算滑动过程中的过渡色 private val argbEvaluator = ArgbEvaluator() override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) { // 非最后一页时计算过渡色 if (position < pageStatusBarColors.size - 1) { val transitionColor = argbEvaluator.evaluate( positionOffset, pageStatusBarColors[position], pageStatusBarColors[position + 1] ) as Int // 同步修改状态栏颜色 window.statusBarColor = transitionColor // 同步调整状态栏字体颜色,避免浅色背景下字体看不清 updateStatusBarTextStyle(transitionColor) } } override fun onPageSelected(position: Int) { // 滑动结束后确认最终颜色,避免边界位置出现色差 window.statusBarColor = pageStatusBarColors[position] updateStatusBarTextStyle(pageStatusBarColors[position]) } override fun onPageScrollStateChanged(state: Int) = Unit })
针对ViewPager2
viewPager2.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { private val argbEvaluator = ArgbEvaluator() override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) { super.onPageScrolled(position, positionOffset, positionOffsetPixels) if (position < pageStatusBarColors.size - 1) { val transitionColor = argbEvaluator.evaluate( positionOffset, pageStatusBarColors[position], pageStatusBarColors[position + 1] ) as Int window.statusBarColor = transitionColor updateStatusBarTextStyle(transitionColor) } } override fun onPageSelected(position: Int) { super.onPageSelected(position) window.statusBarColor = pageStatusBarColors[position] updateStatusBarTextStyle(pageStatusBarColors[position]) } })
3. 状态栏字体颜色适配方法
根据状态栏背景亮度自动切换深色/浅色字体,避免内容看不清:
private fun updateStatusBarTextStyle(backgroundColor: Int) { // API 23及以上支持修改状态栏字体颜色 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { val luminance = Color.luminance(backgroundColor) window.decorView.systemUiVisibility = if (luminance > 0.5f) { // 背景亮度高,用深色字体 View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR } else { // 背景亮度低,用浅色字体 0 } } }
注意事项
window.statusBarColor属性仅在API 21(Android 5.0)及以上系统生效,低于该版本的系统无法修改状态栏背景,可自行添加版本判断做兼容- 确保Activity的主题没有设置固定的
android:statusBarColor属性,也不要强制设置透明状态栏,否则修改会不生效 - 如果使用了Fragment作为ViewPager的页面载体,需要确保修改状态栏颜色的逻辑在宿主Activity中执行
内容的提问来源于stack exchange,提问作者Hoànganh Nguyễn
相关产品推荐
相关产品推荐

