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

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

相关推荐
书弋江山14 分钟前
flutter 跨平台编码库 protobuf 工具使用
android·flutter
来来走走3 小时前
Flutter开发 webview_flutter的基本使用
android·flutter
Jerry说前后端3 小时前
Android 组件封装实践:从解耦到架构演进
android·前端·架构
louisgeek4 小时前
Android OkHttp Interceptor
android
大王派来巡山的小旋风4 小时前
Kotlin基本用法三
android·kotlin
Jerry说前后端5 小时前
Android 移动端 UI 设计:前端常用设计原则总结
android·前端·ui
bytebeats5 小时前
Jetpack Compose 1.9: 核心新特性简介
android·android jetpack
Icey_World5 小时前
Mysql笔记-错误条件\处理程序
android
大王派来巡山的小旋风6 小时前
Kotlin基本用法之集合(一)
android·程序员·kotlin
用户2018792831676 小时前
智能广播系统(RemoteCallbackList)的诞生
android