当前位置: 首页 > 知识库问答 >
问题:

透明状态栏(带有可见的导航栏)

华阳秋
2023-03-14

我知道这个问题已经被问过很多次了,但是所有的答案要么不起作用,要么使用不推荐的代码:

  • Android完全透明的状态栏
  • 透明状态栏-Android 4.4(KitKat)之前的版本
  • Lollipop:在状态栏后面绘制,颜色设置为透明

我想实现与最新的谷歌地图应用程序相同的效果:

  • 完全透明的状态栏(只有状态栏,而不是导航栏!)

WindowCompat.setDecorFitsSystemWindows(窗口,假)部分工作,因为它还隐藏了导航栏

共有3个答案

白智
2023-03-14

我通过以下方法获得了类似的结果。

    <style name="Theme.WebImageDownloader" parent="Theme.MaterialComponents.DayNight.NoActionBar">
     
    // make status bar icons colour grey
    <item name="android:windowLightStatusBar">true</item>
    // override the notch area
    <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
    // make status bar transparent
    <item name="android:windowTranslucentStatus">true</item>
    // make navigation are transparent
    <item name="android:windowTranslucentNavigation">true</item>
   </style>

并在清单中设置上述主题

 android:theme="@style/Theme.WebImageDownloader">

此外,我在活动中放置了工具栏,如下所示:,

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@android:color/holo_blue_dark"
android:layout_height="match_parent">

// other views 

<androidx.appcompat.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="32dp"
    android:minHeight="?attr/actionBarSize"
    android:theme="@style/ToolBarStyle" />

</RelativeLayout>

有“工具栏风格”,你可以有任何颜色的背景,文字等。

陆啸
2023-03-14
匿名用户

要使状态栏完全透明,

首先,在主题中或通过代码将其颜色设置为透明:

//In Theme
<item name="android:statusBarColor">@android:color/transparent</item>
//In Code
window.statusBarColor = android.R.color.transparent

然后,要绘制StatusBar后面的视图,请使用以下代码:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
    window.setDecorFitsSystemWindows(false)
} else {
    window.setFlags(
        WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
        WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
    )
}

您还可以使用布尔属性Android:windowLightStatusBar,它将状态栏的文本和图标颜色设置为黑色或白色,您也可以通过编程实现。如果不想隐藏导航栏,也可以将其设置为颜色。

输出:

https://imgs.xnip.cn/cj/n/26/20d22b40-ae92-49e3-9901-8d5f1a197ac6.png" width="100%" height="100%" />

松越
2023-03-14

步骤1:要使状态栏透明:将以下内容添加到样式themes.xmlsytles.xml中:

<item name="android:windowTranslucentStatus" tools:targetApi="kitkat">true</item>

<item name="android:statusBarColor" tools:targetApi="lollipop">@android:color/transparent</item>

第二步:然后在活动中使状态栏与活动重叠:

从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上是正确的,原因是设置

实际上,

不管怎样,解决这个问题的方法是覆盖主题。xml/样式。API-30中的xml;i、 e.拥有res\values-v30\主题。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上发现了一个错误,底部导航与隐藏底部的活动重叠,OP可能无法发现,因为他们正在使用地图。

为了解决这个问题,根据文件:

您可以通过响应插图来解决重叠问题,插图指定屏幕的哪些部分与系统用户界面相交,如导航栏或状态栏。相交可能意味着简单地显示在内容上方,但它也可以通知您的应用程序系统手势。

因此,我们需要处理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台设备/模拟器上进行了测试。

 类似资料:
  • 在尝试为 Android 实现透明导航和状态栏(边缘到边缘)时,我遵循了本指南。我正在使用自定义顶部栏,以便我可以在滚动时隐藏它。 我将 添加到我的 MainActivity 中。然后,在我的 Fragment 中,我使用插图来向上推送 UI,以便 3 按钮导航不会覆盖某些可点击的界面。 我的主题是这样的: 但我添加的那些插图并不透明。这是一张他们看起来的照片:屏幕截图。请注意,手势导航栏的颜色不

  • 只有在第一次打开应用程序时,半透明的状态栏才会出现问题。请看屏幕截图: http://i1335.photobucket.com/albums/w673/ductruongcntt/Screenshot_2014-06-26-14-17-26_zps1e9a56f4.png 以下是我使用的样式的XML,其中包括半透明状态栏: 我的主题是:

  • 我想制作一个完全透明的状态栏和导航栏,就像Google Play那样。当我使用窗口设置来实现它时,键盘会覆盖编辑文本。 当此代码使用键盘输入覆盖的编辑文本时: 此外,该代码并没有使其完全透明,它只是使其半透明 还是这个

  • 我想在我的应用程序上有一个透明的状态栏(所以背景在后面),但我希望底部的导航栏保持黑色。 我可以通过设置

  • 我一直在寻找一种方法,在状态栏完全透明(而不是半透明)的情况下重新给导航栏上色。要使状态栏完全透明,需要将布局标志设置为无限制,但这也会使导航栏失去颜色。有没有办法做到这一点?

  • 我不确定这是否可行,但我正在尝试在不使状态栏透明的情况下使导航栏透明。之所以选择后者,是因为我有一个工具栏,如果不是这样的话,它会在状态栏后面绘制。 现在,我正在使用一个fakeStatusBar布局,它显示在状态栏之前,这样用户就可以看到所有的东西: 唯一的问题是,在进行多任务处理时,缩略图看起来不太好,因为工具栏不在它应该位于的位置。