首页 > 编程知识 正文

miui 13状态栏样式怎么改,windows 11状态栏透明

时间:2023-05-05 18:38:54 阅读:250875 作者:842

Android Jetpack Compose 沉浸式/透明状态栏 ProvideWindowInsets SystemUiController 前言代码解析添加依赖FitsSystemWindows透明状态栏内容不挡住状态栏 完事

前言

从现在开始疯狂学习Jetpack Compose,经过一早上的研究带来第一篇文章,沉浸式/透明状态栏

代码

懒得看研究过程的朋友可以直接参考最终结果:

import android.content.Intentimport android.os.Bundleimport androidx.activity.ComponentActivityimport androidx.activity.compose.setContentimport androidx.core.view.WindowCompatimport androidx.compose.material.*import androidx.compose.runtime.Composableimport androidx.compose.runtime.SideEffectimport androidx.compose.ui.Modifierimport androidx.compose.ui.graphics.Colorimport androidx.compose.ui.platform.LocalContextimport androidx.compose.ui.tooling.preview.Previewimport androidx.compose.ui.unit.dpimport com.google.accompanist.insets.LocalWindowInsetsimport com.google.accompanist.insets.ProvideWindowInsetsimport com.google.accompanist.insets.rememberInsetsPaddingValuesimport com.google.accompanist.insets.statusBarsPaddingimport com.google.accompanist.systemuicontroller.rememberSystemUiControllerclass MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) WindowCompat.setDecorFitsSystemWindows(window, false) setContent { BD_ToolTheme { ProvideWindowInsets { val systemUiController = rememberSystemUiController() SideEffect { systemUiController.setStatusBarColor(Color.Transparent, darkIcons = false) } Surface( color = MaterialTheme.colors.background ) { Column { com.google.accompanist.insets.ui.TopAppBar( title = { Text(text = "首页") }, contentPadding = rememberInsetsPaddingValues( insets = LocalWindowInsets.current.statusBars) ) Text(text = "你好") } } } } } }}

效果如图:

解析

本篇文章的所有了解来源于这个链接https://google.github.io/accompanist/insets/

当然了,纯英文的,带着翻译工具冲就完事了。

添加依赖 repositories { mavenCentral()}dependencies { implementation "com.google.accompanist:accompanist-insets:$accompanist_version" implementation "com.google.accompanist:accompanist-insets-ui:$accompanist_version" implementation "com.google.accompanist:accompanist-systemuicontroller:$accompanist_version"}

我写下这篇文章时,最新版本为 accompanist_version = "0.15.0"

FitsSystemWindows

第一行代码

WindowCompat.setDecorFitsSystemWindows(window, false)

我们跳转到源码去看看描述

/** * Sets whether the decor view should fit root-level content views for WindowInsetsCompat. * If set to false, the framework will not fit the content view to the insets and will just pass through the WindowInsetsCompat to the content view. * Please note: using the View.setSystemUiVisibility(int) API in your app can conflict with this method. Please discontinue use of View.setSystemUiVisibility(int). * Params: * window – The current window. * decorFitsSystemWindows – Whether the decor view should fit root-level content views for insets. */public static void setDecorFitsSystemWindows(@NonNull Window window, final boolean decorFitsSystemWindows) { if (Build.VERSION.SDK_INT >= 30) { Impl30.setDecorFitsSystemWindows(window, decorFitsSystemWindows); } else if (Build.VERSION.SDK_INT >= 16) { Impl16.setDecorFitsSystemWindows(window, decorFitsSystemWindows); } }

可以看出,当设置成false,就不再使用原定的间隔框架,我们的页面也就不再受状态栏的影响。

If set to false, the framework will not fit the content view to the insets and will just pass through the WindowInsetsCompat to the content view.
如果设置为false,框架将不会将内容视图与嵌入物相适应,而只是将WindowInsetsCompat传递给内容视图。

文字描述总是乏味的,上代码

首先,将decorFitsSystemWindows设置为true override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) WindowCompat.setDecorFitsSystemWindows(window, true) setContent { BD_ToolTheme { Text(text = "首页rn首页1rn首页2rn首页3") } } }

效果如下:

可以看到第一个首页,是紧贴着状态栏的。

接着,将decorFitsSystemWindows设置为false override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) WindowCompat.setDecorFitsSystemWindows(window, false) setContent { BD_ToolTheme { Text(text = "首页rn首页1rn首页2rn首页3") } } }

效果如下:

可以看到第一个首页,其实已经藏在了状态栏的后面了。

透明状态栏

上一步我们已将内容铺满全屏了,这一步就应该将状态改成透明,将我们的内容显示出来。
而这一步我们用到的就是SystemUiController。

override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) WindowCompat.setDecorFitsSystemWindows(window, false) setContent { BD_ToolTheme { rememberSystemUiController().setStatusBarColor( Color.Transparent, darkIcons = MaterialTheme.colors.isLight) Text(text = "首页rn首页1rn首页2rn首页3") } } }


拿到 SystemUiController 的实例,是使用rememberSystemUiController()这个方法,看到remember开头,就知道这是一个观察者的值,然后使用 SystemUiController 的实例去调用方法setStatusBarColor,这个方法有3个参数

fun setStatusBarColor(// 状态栏的颜色 color: Color, // 是否为深色图标 darkIcons: Boolean = color.luminance() > 0.5f, // 如果要求使用深色图标但没有,将调用一个lambda来转换颜色。默认情况下是应用一个黑色框框。 transformColorForLightContent: (Color) -> Color = BlackScrimmed)

我们设置颜色为透明Color.Transparent,是否为深色图标就根据是否在深色模式来判断MaterialTheme.colors.isLight

内容不挡住状态栏

上一步已经将内容显示出来的,那么怎么将它往下移一点,不要和状态栏给重叠了呢?
这就要用到ProvideWindowInsets了。我们需要在显示内容的外围包一层ProvideWindowInsets,这样子,我们的显示内容才能读取到真正的状态栏高度之类的值。

举例:我们先不用ProvideWindowInsets

override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) WindowCompat.setDecorFitsSystemWindows(window, false) setContent { BD_ToolTheme { rememberSystemUiController().setStatusBarColor( Color.Transparent, darkIcons = MaterialTheme.colors.isLight) Column { // 先显示一个空白在上面,高度是状态栏高度 Spacer(modifier = Modifier .statusBarsHeight() .fillMaxWidth()) Text(text = "首页rn首页1rn首页2rn首页3") } } } }


可以看出Spacer并没有生效,说明这时候读取到的状态栏高度是0.

这个时候我们加入ProvideWindowInsets

override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) WindowCompat.setDecorFitsSystemWindows(window, false) setContent { BD_ToolTheme { // 加入ProvideWindowInsets ProvideWindowInsets { rememberSystemUiController().setStatusBarColor( Color.Transparent, darkIcons = MaterialTheme.colors.isLight) Column { Spacer(modifier = Modifier .statusBarsHeight() .fillMaxWidth()) Text(text = "首页rn首页1rn首页2rn首页3") } } } } }


明显可以看出Spacer生效了,能读取到系统状态栏的高度了

可以在跳转进statusBarsHeight()这个方法,可以看到其实是读取了这个值:LocalWindowInsets.current.statusBars,所以也可以改写成rememberInsetsPaddingValues(insets = LocalWindowInsets.current.statusBars)

完事

到这里基本的逻辑已经讲完了,可能有同学发现有个东西我没有讲到SideEffect,为什么需要用这个来包着我们的状态栏颜色设置呢?这个有机会再开一篇文章来说。

什么是ssh

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。