在部分定制系统中,实现真正的沉浸式全屏往往会遇到:
- 顶部黑边
- 内容无法延伸到状态栏
- 状态栏文字颜色不可控
- 不同系统表现不一致
本文给出一套主题 + WindowInsetsControllerCompat 的完整解决方案。
一、目标效果
实现以下能力:
- 内容延伸到状态栏和导航栏区域
- 系统栏透明
- 导航栏自动隐藏(沉浸式粘性)
- 可动态控制状态栏/导航栏图标颜色
适用于:
- 手机
- 车机
- 部分鸿蒙兼容 Android 系统
二、主题配置(Theme)
首先在 App Theme 中开启系统栏绘制权限并设为透明:
java
<!-- 应用的主主题 -->
<style name="Theme.SuperProject" parent="Base.Theme.AudiSuperProject">
<!-- 全屏沉浸状态栏 -->
<item name="android:windowTranslucentStatus">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowLightStatusBar">true</item>
<!-- 透明导航栏 -->
<item name="android:windowTranslucentNavigation">false</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
<!-- 背景和颜色配置 -->
<item name="android:windowBackground">@drawable/icon_splash_img</item>
<item name="colorPrimary">@color/transparent</item>
<item name="colorPrimaryDark">@color/transparent</item>
<item name="colorAccent">@color/transparent</item>
<item name="android:windowEnableSplitTouch">false</item>
<item name="android:splitMotionEvents">false</item>
</style>
说明
- windowDrawsSystemBarBackgrounds=true:允许应用绘制系统栏背景
- statusBarColor / navigationBarColor 设为透明,使内容可以延伸到系统栏区域
- windowLightStatusBar=true:默认使用深色状态栏文字,适配浅色背景
三、动态控制状态栏文字颜色
部分页面背景为浅色或深色时,需要动态切换状态栏文字颜色:
java
/**
* 设置沉浸式模式,同时控制状态栏文字颜色
*
* @param dark true = 黑色文字(适合浅色背景)
* false = 白色文字(适合深色背景)
*/
public void setStatusBarTextColor(boolean dark) {
Window window = getWindow();
View decorView = window.getDecorView();
// 1. 设置状态栏和导航栏透明
window.setStatusBarColor(Color.TRANSPARENT);
window.setNavigationBarColor(Color.TRANSPARENT);
// 2. 使用 WindowInsetsControllerCompat 控制文字颜色
WindowInsetsControllerCompat controller =
new WindowInsetsControllerCompat(window, decorView);
controller.setAppearanceLightStatusBars(dark);
controller.setAppearanceLightNavigationBars(dark);
// 3. 设置系统UI标志,实现内容延伸 + 隐藏导航栏 + 粘性沉浸
int flags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
decorView.setSystemUiVisibility(flags);
// 4. WindowInsets监听,保证布局稳定
decorView.setOnApplyWindowInsetsListener((v, insets) -> insets);
}
使用 WindowInsetsControllerCompat 的优势
- 兼容 Android 11+ 新系统
- 在定制系统环境下稳定性更好
- 不容易被系统自动重置状态栏样式
四、推荐调用方式
在 Activity 的 onCreate() 中:
java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStatusBarTextColor(true); // 设置状态栏文字颜色
setContentView(R.layout.activity_main);
}
五、总结
本文基于实际项目中的沉浸式适配代码,从主题配置到系统 UI 控制,再到状态栏文字颜色动态切换,形成了一套完整且可落地的实现方案。通过合理组合 Theme 属性,可避免顶部黑边、布局受限等常见问题。