Compose 沉寝式状态栏与刘海屏
全屏主题配置,快捷方法 右击创建全屏Activity,只需要保留Theme,其他删除 new>Activity>Fullscreen Views Activity
ini
<style name="Theme.HelloFigmaTwo" parent="android:Theme.Material.Light.NoActionBar" />
//主要是继承无标题主题android:Theme.Material.Light.NoActionBar
<style name="Theme.HelloFigmaTwo.Fullscreen" parent="Theme.HelloFigmaTwo">
<item name="android:actionBarStyle">@style/Widget.Theme.HelloFigmaTwo.ActionBar.Fullscreen
</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowBackground">@null</item>
</style>
ini
<activity
android:name=".StatusBarActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:exported="true"
android:label="@string/title_activity_status_bar"
android:theme="@style/Theme.HelloFigmaTwo.Fullscreen"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Theme.kt中主题配置,这是沉寝式核心部分,Android 30前后差异兼容
ini
@Composable
fun HelloFigmaTwoTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
// Dynamic color is available on Android 12+
dynamicColor: Boolean = true,
content: @Composable () -> Unit
) {
val colorScheme = when {
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
val context = LocalContext.current
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
}
darkTheme -> DarkColors
else -> LightColors
}
val view = LocalView.current
if (!view.isInEditMode) {
SideEffect {
val activity = (view.context as Activity)
val window = activity.window
activity.actionBar?.hide()
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
val compat = WindowCompat.getInsetsController(window, view);
compat.isAppearanceLightStatusBars = true
compat.isAppearanceLightNavigationBars = false
compat.show(WindowInsetsCompat.Type.statusBars() or WindowInsetsCompat.Type.navigationBars())
compat.hide(WindowInsetsCompat.Type.captionBar())
compat.systemBarsBehavior =
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
window.statusBarColor = Color.TRANSPARENT//colorScheme.primary.toArgb()
if (compat.isAppearanceLightStatusBars) {
//状态栏 全屏 黑色字体
window.decorView.systemUiVisibility =
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR or
View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
// View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or
// View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
} else {
//状态栏 全屏 白色字体
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
// View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or
// View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
}
}
}
MaterialTheme(
colorScheme = colorScheme,
typography = Typography,
content = content
)
}
scss
//状态栏
WindowInsetsCompat.Type.statusBars()
//虚拟导航栏
WindowInsetsCompat.Type.navigationBars()
//标题栏
WindowInsetsCompat.Type.captionBar()
//输入键盘
WindowInsetsCompat.Type.ime()
//状态栏+标题栏+虚拟导航栏
WindowInsetsCompat.Type.systemBars()
Compose 中的窗口边衬区
Compose通过Modifier
可以直接设置窗口边界区域
带参 WindowInsets
方式一,直接设置边衬区模式
scss
.windowInsetsPadding(WindowInsets.safeDrawing)
.windowInsetsPadding(WindowInsets.safeGestures)
.windowInsetsPadding(WindowInsets.safeContent)
.windowInsetsPadding(WindowInsets.displayCutout)
方式二,根据需要灵活设置边衬区
scss
Column(Modifier.verticalScroll(rememberScrollState())) {
Spacer(Modifier.windowInsetsTopHeight(WindowInsets.systemBars))
Column(
Modifier.consumeWindowInsets(
WindowInsets.systemBars.only(WindowInsetsSides.Vertical)
)
) {
// content
Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.ime))
}
Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.systemBars))
}
方式三,直接全局窗口引用Padding,注意状态边距和刘海边距存在互斥
scss
.statusBarsPadding()
.displayCutoutPadding()
.imePadding()
.navigationBarsPadding()