一 让activity ui界面和手机状态栏一样的背景
要让 Activity
的 UI 界面和手机状态栏具有相同的背景颜色,并且能够随着深色模式和非深色模式的切换而改变颜色,你可以按照以下步骤操作:
1. 让 Activity 和 状态栏背景颜色一致
使用 window.setFlags
和 window.decorView
来使状态栏透明,让 Activity
的背景可以扩展到状态栏区域。
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
window.statusBarColor = Color.TRANSPARENT // 让状态栏背景透明
然后在 Activity
的根布局(通常是 ConstraintLayout
或 FrameLayout
)的 background
设置颜色,使其填充整个界面,包括状态栏。
2. 让颜色支持深色和非深色模式
可以在 res/values/colors.xml
和 res/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 界面和状态栏的背景一致,并减少代码重复。
是的,推荐在 BaseActivity
的 onCreate
方法中写这段代码,然后让所有 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_STABLE
window.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_MASK
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
}
}
然后在 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_STABLE
window.statusBarColor = Color.TRANSPARENT
// 设置背景颜色
setActivityBackground()
}
private fun setActivityBackground() {
// 获取当前的夜间模式状态
val nightModeFlags = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
val 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.xml
和 res/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.TRANSPARENT
window.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_MASK
val 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
}
}
}