第1步:要使状态栏透明:在样式themes.xml或sytles.xml中添加以下内容:
<item name="android:windowTranslucentStatus" tools:targetApi="kitkat">true</item>
<item name="android:statusBarColor" tools:targetApi="lollipop">@android:color/transparent</item>
第二步:然后在activity中让状态栏与activity重叠:
使用的窗口标志从 API 级别 30 起已弃用,因此它们可以在 API 级别 29 之前使用:
if (Build.VERSION.SDK_INT in 21..29) {
window.statusBarColor = Color.TRANSPARENT
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
window.decorView.systemUiVisibility =
SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or SYSTEM_UI_FLAG_LAYOUT_STABLE
} else if (Build.VERSION.SDK_INT >= 30) {
window.statusBarColor = Color.TRANSPARENT
// Making status bar overlaps with the activity
WindowCompat.setDecorFitsSystemWindows(window, false)
}
API-30 更新
这实际上并没有使状态栏透明,它使它成为半透明并且仍然会有阴影
这在 API-30 上是正确的,原因是设置 <item name="android:windowTranslucentStatus">true</item>。
实际上,<item name="android:windowTranslucentStatus">true</item> 仅在 API 级别 19 上是必需的。如果您的应用比这更高,您可以完全关闭它。
无论如何,解决这个问题的方法是覆盖 API-30 中的themes.xml/styles.xml;即拥有res\values-v30\themes.xml;您可以添加主应用主题,例如:
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.TransparentStatusBar" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_500</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_700</item>
<item name="colorOnSecondary">@color/black</item>
</style>
</resources>
API-30 更新 2
刚刚在 API 30 上发现了一个错误,即底部导航与隐藏其底部的 Activity 重叠,OP 在使用地图时可能无法发现。
要解决这个问题,As per documentation:
您可以通过对插图做出反应来解决重叠问题,插图指定了哪些
屏幕的某些部分与导航等系统 UI 相交
栏或状态栏。相交可能意味着简单地显示
上面的内容,但它也可以通知你的应用程序关于系统
手势也是。
因此,我们需要处理 API 级别 30+ 的系统栏插入,以避免您的应用与导航栏重叠:
这需要活动布局的顶部根ViewGroup,因此LayoutParams需要适当地滑行。
这里我使用ConstraintLayout 作为根布局,FrameLayout.LayoutParams:
/*
* Making the Navigation system bar not overlapping with the activity
*/
if (Build.VERSION.SDK_INT >= 30) {
// Root ViewGroup of my activity
val root = findViewById<ConstraintLayout>(R.id.root)
ViewCompat.setOnApplyWindowInsetsListener(root) { view, windowInsets ->
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
// Apply the insets as a margin to the view. Here the system is setting
// only the bottom, left, and right dimensions, but apply whichever insets are
// appropriate to your layout. You can also update the view padding
// if that's more appropriate.
view.layoutParams = (view.layoutParams as FrameLayout.LayoutParams).apply {
leftMargin = insets.left
bottomMargin = insets.bottom
rightMargin = insets.right
}
// Return CONSUMED if you don't want want the window insets to keep being
// passed down to descendant views.
WindowInsetsCompat.CONSUMED
}
}
这是在 API 级别 19 到 API 级别 30 的 8 台设备/模拟器上测试的。