Compose 沉寝式状态栏与刘海屏

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()

状态栏刘海屏设置官方介绍

相关推荐
海水冷却33 分钟前
Android 群组聊天怎么实现:基于 ZIM 的完整落地指南(附可运行 Demo)
android
三少爷的鞋3 小时前
现代 Android 架构指南:不要再主动设计 Callback 接口
android
TimeFine9 小时前
AI 编码工作流的设计
android·ai编程
骑着蜗牛撵大象32710 小时前
C++20 协程 × 屏障:手写一个 co_await 版 Barrier,让等待不再钉死线程
android·c++20·协程·并发编程·co_await·屏障同步
山东孙燕姿11 小时前
设备台账重构:从一张表到三层模型
android·java·网络·低代码·重构·rxjava
蒸鱼Yuzheng12 小时前
移动端 CPU 调度分析:线程亲和性、大小核迁移与卡顿
android·perfetto·性能分析·线程优化·cpu调度
booboosui12 小时前
安卓唤醒词:12 维 MFCC 加 DTW,阈值 1.8
android
传奇开心果12 小时前
Compose Multiplatform 共享边界实战:架构契约、互操作同步与可回退设计
android·kotlin
事圆则缓13 小时前
从开机到首帧:Android 系统与应用启动流程源码分析
android
AI吃大瓜13 小时前
指针压力表读数4:Android实现指针压力表读数(可实时检测)
android·指针读数·指针压力表·压力表·压力表读数