当前位置: 首页 > news >正文

android 设置状态栏背景

一 让activity ui界面和手机状态栏一样的背景

要让 Activity 的 UI 界面和手机状态栏具有相同的背景颜色,并且能够随着深色模式和非深色模式的切换而改变颜色,你可以按照以下步骤操作:


1. 让 Activity 和 状态栏背景颜色一致

使用 window.setFlagswindow.decorView 来使状态栏透明,让 Activity 的背景可以扩展到状态栏区域。

window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
window.statusBarColor = Color.TRANSPARENT // 让状态栏背景透明

然后在 Activity 的根布局(通常是 ConstraintLayoutFrameLayout)的 background 设置颜色,使其填充整个界面,包括状态栏。


2. 让颜色支持深色和非深色模式

可以在 res/values/colors.xmlres/values-night/colors.xml 定义不同模式下的颜色。

  • res/values/colors.xml(浅色模式颜色)
<color name="background_color">#FFFFFF</color>
  • res/values-night/colors.xml(深色模式颜色)
<color name="background_color">#121212</color>

然后在 Activity 中应用此颜色:

val rootView = findViewById<View>(android.R.id.content)
rootView.setBackgroundColor(ContextCompat.getColor(this, R.color.background_color))

3. 让状态栏颜色也随着模式切换

可以动态更新状态栏颜色:

val window = window
window.statusBarColor = ContextCompat.getColor(this, R.color.background_color)

或者直接使用 theme 属性:

<style name="Theme.MyApp" parent="Theme.MaterialComponents.DayNight"><item name="android:statusBarColor">@color/background_color</item>
</style>

这样,Activity 的背景和状态栏颜色在深色模式和浅色模式下都会自动切换。

二 代码优化

让所有 Activity 继承 BaseActivity,这样可以保证整个应用的 Activity 界面和状态栏的背景一致,并减少代码重复。

是的,推荐在 BaseActivityonCreate 方法中写这段代码,然后让所有 Activity 继承 BaseActivity,这样可以保证整个应用的 Activity 界面和状态栏的背景一致,并减少代码重复。


1. 在 BaseActivity 统一设置状态栏

创建 BaseActivity 并在 onCreate 里设置 UI:

open class BaseActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// 设置状态栏透明,并让内容扩展到状态栏区域window.decorView.systemUiVisibility =View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLEwindow.statusBarColor = Color.TRANSPARENT // 让状态栏背景透明}
}

2. 让其他 Activity 继承 BaseActivity

在应用中的 Activity 继承 BaseActivity,例如:

class MainActivity : BaseActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)}
}

3. 适配深色模式的状态栏文本颜色

如果你想要在 深色模式时让状态栏的文字颜色变白,在 浅色模式时让状态栏的文字变黑,可以根据当前模式动态调整:

private fun updateStatusBarTextColor() {val nightModeFlags = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASKif (nightModeFlags == Configuration.UI_MODE_NIGHT_YES) {window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN} else {window.decorView.systemUiVisibility =View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR}
}

然后在 onCreate 里调用它:

updateStatusBarTextColor()

这样就可以在 BaseActivity 里集中管理状态栏样式,每个 Activity 都会继承相同的 UI 规则,保持一致性,同时还能适配深色模式。

三 在 BaseActivity 里统一设置背景颜色

android.R.id.content,它是 Android 默认提供的 根视图容器,包含 Activity 的所有视图

不需要在 Activity 的根布局中声明 android.R.id.content,它是 Android 默认提供的 根视图容器,包含 Activity 的所有视图。
但是,在每个 Activity 里都手动调用 setBackgroundColor() 确实有些繁琐,建议把它也放到 BaseActivity 里统一处理。


优化方案:在 BaseActivity 里统一设置背景颜色

这样每个 Activity 只需要继承 BaseActivity,就能自动适配深色和浅色模式。

1. 修改 BaseActivity

open class BaseActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// 设置状态栏透明,让内容扩展到状态栏区域window.decorView.systemUiVisibility =View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLEwindow.statusBarColor = Color.TRANSPARENT// 设置背景颜色setActivityBackground()}private fun setActivityBackground() {// 获取当前的夜间模式状态val nightModeFlags = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASKval backgroundColor = if (nightModeFlags == Configuration.UI_MODE_NIGHT_YES) {ContextCompat.getColor(this, R.color.background_color) // 夜间模式颜色} else {ContextCompat.getColor(this, R.color.background_color) // 日间模式颜色}// 设置根布局的背景颜色findViewById<View>(android.R.id.content).setBackgroundColor(backgroundColor)// 设置状态栏文本颜色if (nightModeFlags == Configuration.UI_MODE_NIGHT_YES) {window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN} else {window.decorView.systemUiVisibility =View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR}
}

2. 让其他 Activity 继承 BaseActivity

Activity 里无需再设置背景:

class MainActivity : BaseActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)}
}

3. 让 R.color.background_color 适配深色模式

确保 res/values/colors.xmlres/values-night/colors.xml 里都定义了 background_color

  • 浅色模式 (res/values/colors.xml)
    <color name="background_color">#FFFFFF</color>
    
  • 深色模式 (res/values-night/colors.xml)
    <color name="background_color">#121212</color>
    

这样 BaseActivity 统一管理背景颜色,所有 Activity 都自动继承,无需每个 Activity 里手动设置,代码更整洁!

2 完整代码示例

open class BaseActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// 设置状态栏透明window.statusBarColor = Color.TRANSPARENTwindow.decorView.systemUiVisibility =View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE// 统一设置 Activity 背景setActivityBackground()}private fun setActivityBackground() {val nightModeFlags = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASKval backgroundColor = ContextCompat.getColor(this, R.color.background_color)// 设置根布局背景颜色findViewById<View>(android.R.id.content).setBackgroundColor(backgroundColor)// 设置状态栏文本颜色if (nightModeFlags == Configuration.UI_MODE_NIGHT_YES) {window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN} else {window.decorView.systemUiVisibility =View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR}}
}

四 android 设置状态栏背景-沉浸式状态栏

问题 1:代码含义及两个属性的作用

Material Design 3 的 Theme.Material3.DayNight.NoActionBar 主题。主题用于统一应用的外观和风格。

代码解析:
<style name="Base.Theme.IC_ACScreen" parent="Theme.Material3.DayNight.NoActionBar"><!-- 自定义亮色主题的属性 --><!-- <item name="colorPrimary">@color/my_light_primary</item> --><item name="android:statusBarColor">@color/background_color</item><item name="android:windowBackground">@android:color/white</item>
</style>
  • <item name="android:statusBarColor">@color/background_color</item>

    • 这个属性设置了状态栏的颜色。状态栏是屏幕顶部显示时间、电池状态、信号等信息的区域。
    • 在这里,状态栏的颜色被设置为 @color/background_color,即一个自定义颜色资源。
  • <item name="android:windowBackground">@android:color/white</item>

    • 这个属性设置了窗口的背景颜色。窗口背景是指整个应用界面的默认背景。
    • 在这里,窗口背景被设置为白色(@android:color/white)。

问题 2: <item name="android:statusBarColor">@color/background_color</item> 设置无效

BaseActivityonCreate 方法中使用了以下代码:

// 设置状态栏透明,并让内容扩展到状态栏区域
window.decorView.systemUiVisibility =View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
window.statusBarColor = Color.TRANSPARENT // 让状态栏背景透明
原因分析:
  1. window.statusBarColor = Color.TRANSPARENT 的优先级更高

    • 在代码中直接设置 window.statusBarColor 的值会覆盖 XML 中的主题属性。
    • 因此,即使在主题中设置了 <item name="android:statusBarColor">@color/background_color</item>,在运行时它会被代码中的 Color.TRANSPARENT 替代。
  2. SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 的作用

    • 这个标志告诉系统将内容布局扩展到状态栏区域,通常用于实现沉浸式体验。
    • 结合 window.statusBarColor = Color.TRANSPARENT,可以让状态栏完全透明,同时内容可以延伸到状态栏下方。
解决方法:

如果希望保留主题中的 android:statusBarColor 设置,而不使用代码中的透明状态栏,可以移除以下代码:

window.decorView.systemUiVisibility =View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
window.statusBarColor = Color.TRANSPARENT

如果需要动态控制状态栏颜色,可以通过代码动态设置,而不是依赖主题中的静态配置。


总结

  1. 两个属性的作用

    • android:statusBarColor:设置状态栏的颜色。
    • android:windowBackground:设置窗口的背景颜色。
  2. 为什么无效

    • 在代码中通过 window.statusBarColor = Color.TRANSPARENT 动态设置了状态栏颜色,覆盖了 XML 中的主题设置。
    • 如果需要使用主题中的颜色,请避免在代码中覆盖它。

SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 的作用

SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 的主要目的是让应用的内容布局延伸到状态栏区域,而不是被限制在状态栏下方。它的具体效果如下:

  1. 内容扩展到状态栏区域

    • 默认情况下,Android 应用的内容会被限制在状态栏下方的区域内。启用 SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 后,应用的内容(如图片、文字等)可以延伸到状态栏区域。
    • 这种效果通常用于实现沉浸式体验,比如全屏图片、视频播放器或背景延伸到状态栏的设计。
  2. 状态栏仍然存在

    • 状态栏本身(显示时间、电池、信号等内容)并不会消失,但其背景颜色可能会被透明化或自定义。
    • 如果状态栏背景是透明的(通过 window.statusBarColor = Color.TRANSPARENT 设置),那么状态栏中的文字和图标会直接叠加在应用内容之上。

是否遮挡状态栏中的文字?

如果不对状态栏的文字和图标进行适配,确实可能导致内容与状态栏文字重叠,影响可读性。因此,在使用 SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 时,需要特别注意以下几点:

1. 设置状态栏文字颜色
  • Android 提供了两种模式来调整状态栏文字的颜色:

    • 深色文字:适合浅色背景。
    • 浅色文字:适合深色背景。
  • 可以通过以下代码动态设置状态栏文字颜色:

    // 设置状态栏文字为深色(适用于浅色背景)
    window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR// 设置状态栏文字为浅色(适用于深色背景)
    window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
    

    注意View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR 仅支持 Android 6.0(API 23)及以上版本。

2. 避免内容与状态栏重叠
  • 如果内容(如工具栏、图片等)延伸到状态栏区域,可以通过设置 fitsSystemWindows 属性来避免内容与状态栏重叠。

  • 在布局文件中添加 android:fitsSystemWindows="true"

    <LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:fitsSystemWindows="true"><!-- 内容 -->
    </LinearLayout>
    

    作用

    • fitsSystemWindows 会让布局自动为系统窗口(如状态栏、导航栏)留出空间,从而避免内容与系统 UI 元素重叠。
3. 透明状态栏的视觉效果
  • 如果状态栏完全透明,同时内容延伸到状态栏区域,可以结合以下设置:
    • 设置透明背景:
      window.statusBarColor = Color.TRANSPARENT
      
    • 使用深色或浅色文字模式(根据背景颜色选择合适的文字颜色)。

具体效果示例

假设你有一个全屏图片作为背景,并希望状态栏透明,同时图片延伸到状态栏区域。以下是实现步骤:

  1. 主题设置
    styles.xml 中定义透明状态栏的主题:

    <style name="AppTheme.FullScreen" parent="Theme.Material3.DayNight.NoActionBar"><item name="android:statusBarColor">@android:color/transparent</item><item name="android:windowBackground">@color/background_color</item>
    </style>
    
  2. Activity 中的代码
    onCreate 方法中启用 SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 并设置状态栏文字颜色:

    override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)// 设置状态栏透明并扩展内容到状态栏区域window.decorView.systemUiVisibility =View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN orView.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR // 深色文字
    }
    
  3. 布局文件
    确保根布局设置了 fitsSystemWindows 属性,避免内容与状态栏重叠:

    <ImageViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:src="@drawable/background_image"android:scaleType="centerCrop"android:fitsSystemWindows="true" />
    

总结

  • SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 的效果

    • 让内容布局延伸到状态栏区域,常用于沉浸式设计。
    • 状态栏本身不会消失,但背景可能变为透明或自定义颜色。
  • 如何避免遮挡状态栏文字

    • 设置状态栏文字颜色(深色或浅色)。
    • 使用 fitsSystemWindows 属性避免内容与状态栏重叠。
    • 根据背景颜色选择合适的文字颜色模式。

通过合理配置,可以让状态栏与应用内容完美融合,同时保证用户体验和可读性。


http://www.mrgr.cn/news/96742.html

相关文章:

  • 大模型-提示词(Prompt)技巧
  • OpenLayers:海量图形渲染之矢量切片
  • 4.1学习总结 拼图小游戏+集合进阶
  • 嵌入式EMC设计面试题及参考答案
  • 企业或个人linux服务器搭建
  • kubernetes》》k8s》》Deployment》》ClusterIP、LoadBalancer、Ingress 内部访问、外边访问
  • SOME/IP-SD -- 协议英文原文讲解10
  • 速查Linux常用指令
  • 【Harmonyos】项目开发总结--摇杆拖动侧重实现(适用游戏摇杆)
  • [GESP202503 C++六级题解]:P11963:环线
  • 论文阅读笔记:Denoising Diffusion Implicit Models (3)
  • 利用Canvas在紫微斗数命盘上画出三方四正
  • 大数据(4.3)Hive基础查询完全指南:从SELECT到复杂查询的10大核心技巧
  • 1.2 基于卷积神经网络与SE注意力的轴承故障诊断
  • C++学习day4
  • 企业linux常用服务搭建
  • SSH服务
  • 增加等IO状态的唤醒堆栈打印及缺页异常导致iowait分析
  • 设计模式 三、结构型设计模式
  • CMD(命令提示符)、PowerShell 和 Windows Terminal