【问题标题】:Android Completely transparent Status Bar?Android 完全透明的状态栏?
【发布时间】:2015-03-27 22:15:21
【问题描述】:

我已经搜索了 文档,但只找到了这个: Link。哪个用于使条半透明?我要做的是使状态栏完全透明(如下图所示)并使其向后兼容 APK

我的样式.xml:

<resources xmlns:tools="http://schemas.android.com/tools">

  <style name="AppTheme" parent="Theme.AppCompat.Light">
  <item name="android:actionBarStyle">@style/ThemeActionBar</item>
  <item name="android:windowActionBarOverlay">true</item>
  <!-- Support library compatibility -->
  <item name="actionBarStyle">@style/ThemeActionBar</item>
  <item name="windowActionBarOverlay">true</item>
  </style>

  <style name="ThemeActionBar" parent="Widget.AppCompat.Light.ActionBar.Solid">
  <item name="android:background"> @null </item>
  <!-- Support library compatibility -->
  <item name="background">@null</item>
  <item name="android:displayOptions"> showHome | useLogo</item>
  <item name="displayOptions">showHome|useLogo</item>

  </style>

</resources>

我能做什么:

【问题讨论】:

标签: android statusbar


【解决方案1】:

您需要做的就是在您的主题中设置这些属性:

<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>

您希望拥有透明状态栏的活动/容器布局需要此属性集:

android:fitsSystemWindows="true"

通常不可能在 pre-kitkat 上确定执行此操作,看起来您可以执行此操作but some strange code makes it so

编辑:我会推荐这个库:https://github.com/jgilfelt/SystemBarTint 用于大量的棒棒糖前状态栏颜色控制。

经过深思熟虑,我了解到完全禁用棒棒糖状态栏和导航栏上的半透明或任何颜色的答案是在窗口上设置此标志:

// In Activity's onCreate() for instance
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    Window w = getWindow();
    w.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}

不需要其他主题,它会产生如下内容:

【讨论】:

  • 我使用了代码,然后添加了一张图片作为背景,然后将android:fitsSystemWindows="true" 添加到我的activity_main.xml 中。系统栏是半透明的,不是透明的。
  • 好吧,我相信在这种情况下您所需要的只是将&lt;item name="android:statusBarColor"&gt;@android:color/transparent&lt;/item&gt; 添加到您的主题中:)
  • 是的,感谢您的耐心等待,因为过去几个小时我一直在尝试这样做,所以我几乎处于倾斜状态 xD。上面的代码不起作用,但是我将android:windowTranslucentStatus 设置为false,它使状态栏变得透明。现在我对导航栏做了同样的事情并添加了&lt;item name="android:navigationBarColor"&gt;@android:color/transparent&lt;/item&gt;,但它使两个栏都变灰了。啊!
  • 要使“adjustPan”工作,请改用w.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
  • 注意:使用 FLAG_LAYOUT_NO_LIMITS 标志也会将您的布局放在底部的虚拟导航栏下。一般来说,你不想这样做......所以同上其他人所说的:-(
【解决方案2】:

只需将这行代码添加到您的主 java 文件中:

getWindow().setFlags(
    WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
    WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
);

【讨论】:

  • 这也会影响导航栏。
  • 这会破坏 SOFT_INPUT_ADJUST_PAN 和 SOFT_INPUT_ADJUST_RESIZE,因此无法滚动
  • 这不适用于安卓一加!
【解决方案3】:

您可以使用下面的代码使状态栏透明。 查看带有红色突出显示的图像,可帮助您识别以下代码的使用

Android 应用的 Kotlin 代码 sn-p

步骤:1在On create Method中写下代码

if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 21) {
    setWindowFlag(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, true)
}
if (Build.VERSION.SDK_INT >= 19) {
    window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
}
if (Build.VERSION.SDK_INT >= 21) {
    setWindowFlag(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, false)
    window.statusBarColor = Color.TRANSPARENT
}

第二步:你需要下面代码中描述的SetWindowFlag方法。

private fun setWindowFlag(bits: Int, on: Boolean) {
    val win = window
    val winParams = win.attributes
    if (on) {
        winParams.flags = winParams.flags or bits
    } else {
        winParams.flags = winParams.flags and bits.inv()
    }
    win.attributes = winParams
}

Android 应用的 Java 代码 sn-p:

第一步:主要活动代码

if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 21) {
    setWindowFlag(this, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, true);
}
if (Build.VERSION.SDK_INT >= 19) {
    getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}

if (Build.VERSION.SDK_INT >= 21) {
    setWindowFlag(this, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, false);
    getWindow().setStatusBarColor(Color.TRANSPARENT);
}

第二步: SetWindowFlag 方法

public static void setWindowFlag(Activity activity, final int bits, boolean on) {
    Window win = activity.getWindow();
    WindowManager.LayoutParams winParams = win.getAttributes();
    if (on) {
        winParams.flags |= bits;
    } else {
        winParams.flags &= ~bits;
    }
    win.setAttributes(winParams);
}

【讨论】:

    【解决方案4】:

    适用于 Android KitKat 及更高版本(对于那些想要透明状态栏且不操纵 NavigationBar 的人,因为所有这些答案也会使 NavigationBar 透明!)

    实现它的最简单方法:

    将这 3 行代码放在 styles.xml (v19) 中 -> 如果您不知道如何使用(v19),只需将它们写在您的默认 styles.xml 中,然后使用 alt +输入自动创建:

    <item name="android:windowFullscreen">false</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:fitsSystemWindows">false</item>
    

    现在,转到您的MainActivity 类并将此方法从类中的 onCreate 中删除:

    public static void setWindowFlag(Activity activity, final int bits, boolean on) {
    
        Window win = activity.getWindow();
        WindowManager.LayoutParams winParams = win.getAttributes();
        if (on) {
            winParams.flags |= bits;
        } else {
            winParams.flags &= ~bits;
        }
        win.setAttributes(winParams);
    }
    

    然后把这段代码放到Activity的onCreate方法中:

    if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 21) {
            setWindowFlag(this, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, true);
        }
        if (Build.VERSION.SDK_INT >= 19) {
            getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
        }
        //make fully Android Transparent Status bar
        if (Build.VERSION.SDK_INT >= 21) {
            setWindowFlag(this, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, false);
            getWindow().setStatusBarColor(Color.TRANSPARENT);
        }
    

    就是这样!

    【讨论】:

    • 根据我在 React Native 中的经验... 上面的代码与显示键盘(adjustResize)有冲突。所以,我只做一些小改动:``` if (Build.VERSION.SDK_INT >= 19) { getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE); } ``` 和 Component ``` ``` 和 AppManisfes - MainActivity ``` android:windowSoftInputMode="adjustResize" ``` 其余代码是相同的。仅供参考:```“react-native”:“0.61.5”,```谢谢@parsa dadras
    • 这正确回答了 OP 的问题。这应该是公认的答案。
    【解决方案5】:

    可以使用外部库StatusBarUtil

    添加到您的模块级别build.gradle

    compile 'com.jaeger.statusbarutil:library:1.4.0'
    

    然后你可以为一个Activity使用下面的util来让状态栏透明:

    StatusBarUtil.setTransparent(Activity activity)
    

    例子:

    【讨论】:

    • 一个只是为了解决这个问题的库,就像用火焰喷射器点燃蜡烛
    【解决方案6】:

    完全透明的状态栏和导航栏

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        transparentStatusAndNavigation();
    }
    
    
    private void transparentStatusAndNavigation() {
        //make full transparent statusBar
        if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 21) {
            setWindowFlag(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
                    | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, true);
        }
        if (Build.VERSION.SDK_INT >= 19) {
            getWindow().getDecorView().setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
            );
        }
        if (Build.VERSION.SDK_INT >= 21) {
            setWindowFlag(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
                    | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, false);
            getWindow().setStatusBarColor(Color.TRANSPARENT);
            getWindow().setNavigationBarColor(Color.TRANSPARENT);
        }
    }
    
    private void setWindowFlag(final int bits, boolean on) {
        Window win = getWindow();
        WindowManager.LayoutParams winParams = win.getAttributes();
        if (on) {
            winParams.flags |= bits;
        } else {
            winParams.flags &= ~bits;
        }
        win.setAttributes(winParams);
    }
    

    【讨论】:

      【解决方案7】:

      在状态栏下绘制布局:

      值/样式.xml

      <item name="android:windowTranslucentStatus">true</item>
      

      values-v21/styles.xml

      <item name="android:windowDrawsSystemBarBackgrounds">true</item>
      <item name="android:statusBarColor">@color/colorPrimaryDark</item>
      

      使用已经处理了 fitSystemWindows 参数的 CoordinatorLayout/DrawerLayout 或创建您自己的布局,如下所示:

      public class FitsSystemWindowConstraintLayout extends ConstraintLayout {
      
          private Drawable mStatusBarBackground;
          private boolean mDrawStatusBarBackground;
      
          private WindowInsetsCompat mLastInsets;
      
          private Map<View, int[]> childsMargins = new HashMap<>();
      
          public FitsSystemWindowConstraintLayout(Context context) {
              this(context, null);
          }
      
          public FitsSystemWindowConstraintLayout(Context context, AttributeSet attrs) {
              this(context, attrs, 0);
          }
      
          public FitsSystemWindowConstraintLayout(Context context, AttributeSet attrs, int defStyleAttr) {
              super(context, attrs, defStyleAttr);
      
              if (ViewCompat.getFitsSystemWindows(this)) {
                  ViewCompat.setOnApplyWindowInsetsListener(this, new android.support.v4.view.OnApplyWindowInsetsListener() {
                      @Override
                      public WindowInsetsCompat onApplyWindowInsets(View view, WindowInsetsCompat insets) {
                          FitsSystemWindowConstraintLayout layout = (FitsSystemWindowConstraintLayout) view;
                          layout.setChildInsets(insets, insets.getSystemWindowInsetTop() > 0);
                          return insets.consumeSystemWindowInsets();
                      }
                  });
                  setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                          | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
                  TypedArray typedArray = context.obtainStyledAttributes(new int[]{android.R.attr.colorPrimaryDark});
                  try {
                      mStatusBarBackground = typedArray.getDrawable(0);
                  } finally {
                      typedArray.recycle();
                  }
              } else {
                  mStatusBarBackground = null;
              }
          }
      
          public void setChildInsets(WindowInsetsCompat insets, boolean draw) {
              mLastInsets = insets;
              mDrawStatusBarBackground = draw;
              setWillNotDraw(!draw && getBackground() == null);
      
              for (int i = 0; i < getChildCount(); i++) {
                  View child = getChildAt(i);
                  if (child.getVisibility() != GONE) {
                      if (ViewCompat.getFitsSystemWindows(this)) {
                          ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams) child.getLayoutParams();
      
                          if (ViewCompat.getFitsSystemWindows(child)) {
                              ViewCompat.dispatchApplyWindowInsets(child, insets);
                          } else {
                              int[] childMargins = childsMargins.get(child);
                              if (childMargins == null) {
                                  childMargins = new int[]{layoutParams.leftMargin, layoutParams.topMargin, layoutParams.rightMargin, layoutParams.bottomMargin};
                                  childsMargins.put(child, childMargins);
                              }
                              if (layoutParams.leftToLeft == LayoutParams.PARENT_ID) {
                                  layoutParams.leftMargin = childMargins[0] + insets.getSystemWindowInsetLeft();
                              }
                              if (layoutParams.topToTop == LayoutParams.PARENT_ID) {
                                  layoutParams.topMargin = childMargins[1] + insets.getSystemWindowInsetTop();
                              }
                              if (layoutParams.rightToRight == LayoutParams.PARENT_ID) {
                                  layoutParams.rightMargin = childMargins[2] + insets.getSystemWindowInsetRight();
                              }
                              if (layoutParams.bottomToBottom == LayoutParams.PARENT_ID) {
                                  layoutParams.bottomMargin = childMargins[3] + insets.getSystemWindowInsetBottom();
                              }
                          }
                      }
                  }
              }
      
              requestLayout();
          }
      
          public void setStatusBarBackground(Drawable bg) {
              mStatusBarBackground = bg;
              invalidate();
          }
      
          public Drawable getStatusBarBackgroundDrawable() {
              return mStatusBarBackground;
          }
      
          public void setStatusBarBackground(int resId) {
              mStatusBarBackground = resId != 0 ? ContextCompat.getDrawable(getContext(), resId) : null;
              invalidate();
          }
      
          public void setStatusBarBackgroundColor(@ColorInt int color) {
              mStatusBarBackground = new ColorDrawable(color);
              invalidate();
          }
      
          @Override
          public void onDraw(Canvas canvas) {
              super.onDraw(canvas);
              if (mDrawStatusBarBackground && mStatusBarBackground != null) {
                  int inset = mLastInsets != null ? mLastInsets.getSystemWindowInsetTop() : 0;
                  if (inset > 0) {
                      mStatusBarBackground.setBounds(0, 0, getWidth(), inset);
                      mStatusBarBackground.draw(canvas);
                  }
              }
          }
      }
      

      main_activity.xml

      <FitsSystemWindowConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:app="http://schemas.android.com/apk/res-auto"
          xmlns:tools="http://schemas.android.com/tools"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:fitsSystemWindows="true">
      
          <ImageView
              android:layout_width="0dp"
              android:layout_height="0dp"
              android:fitsSystemWindows="true"
              android:scaleType="centerCrop"
              android:src="@drawable/toolbar_background"
              app:layout_constraintBottom_toBottomOf="@id/toolbar"
              app:layout_constraintLeft_toLeftOf="parent"
              app:layout_constraintRight_toRightOf="parent"
              app:layout_constraintTop_toTopOf="parent" />
      
          <android.support.v7.widget.Toolbar
              android:id="@+id/toolbar"
              android:layout_width="0dp"
              android:layout_height="?attr/actionBarSize"
              android:background="@android:color/transparent"
              app:layout_constraintLeft_toLeftOf="parent"
              app:layout_constraintRight_toRightOf="parent"
              app:layout_constraintTop_toTopOf="parent" />
      
          <LinearLayout
              android:layout_width="0dp"
              android:layout_height="0dp"
              android:gravity="center"
              app:layout_constraintBottom_toBottomOf="parent"
              app:layout_constraintLeft_toLeftOf="parent"
              app:layout_constraintRight_toRightOf="parent"
              app:layout_constraintTop_toBottomOf="@id/toolbar">
      
              <TextView
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:gravity="center"
                  android:text="Content"
                  android:textSize="48sp" />
          </LinearLayout>
      </FitsSystemWindowConstraintLayout>
      

      结果:

      截图:

      【讨论】:

        【解决方案8】:

        这是一个 kotlin 中的扩展,可以解决问题:

        fun Activity.setTransparentStatusBar() {
            window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                window.statusBarColor = Color.TRANSPARENT
            }
        }
        

        【讨论】:

          【解决方案9】:

          简单明了,适用于几乎所有用例(API 级别 16 及以上):

          1. 在您的应用主题中使用以下标签使状态栏透明:

            &lt;item name="android:statusBarColor"&gt;@android:color/transparent&lt;/item&gt;

          2. 然后在您的活动的 onCreate 方法中使用此代码。

            View decorView = getWindow().getDecorView();
            decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
            

          这就是你需要做的一切;)

          您可以从developer documentation. 了解更多信息,我还建议您阅读this 博客文章。

          KOTLIN 代码

              val decorView = window.decorView
              decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                      or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
          

          查看我的另一个答案here

          【讨论】:

          • 这会破坏 SOFT_INPUT_ADJUST_RESIZE 和 SOFT_INPUT_ADJUST_PAN
          • 'SYSTEM_UI_FLAG_LAYOUT_STABLE 和 SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 已弃用
          • @TheMJ 是的,它们已被弃用,需要进行一些研究以找出替代方案。
          • systemUiVisibility 已弃用
          【解决方案10】:

          在顶部布局中使用android:fitsSystemWindows="false"

          【讨论】:

          • 这也会影响导航栏
          【解决方案11】:

          对于具有日/夜支持的 API > 23,您可以使用下面的扩展。要理解的重要部分是android:fitsSystemWindows="true" 使用填充在插图内移动(就像使用工具栏一样)。因此,把它放在你的根布局是没有意义的(除了 DrawerLayout、CoordinatorLayout,......这些使用它们自己的实现)。

          <style name="Theme.YourApp.DayNight" parent="Theme.MaterialComponents.DayNight.NoActionBar">
              ...
              <item name="android:windowLightStatusBar">@bool/isDayMode</item>
              <item name="android:statusBarColor">@android:color/transparent</item>
          </style>
          
          <androidx.constraintlayout.widget.ConstraintLayout
              ...>
          
              <com.google.android.material.appbar.MaterialToolbar
                  ...
                  android:fitsSystemWindows="true">
          
          </androidx.constraintlayout.widget.ConstraintLayout
          
          fun Activity.transparentStatusBar() {
              if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
                  window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
              } else {
                  window.setDecorFitsSystemWindows(false)
              }
          }
          

          然后这样称呼它:

          class YourActivity : AppCompatActivity() {
              override fun onCreate(savedInstanceState: Bundle?) {
                  super.onCreate(savedInstanceState)
                  ...
                  transparentStatusBar()
              }
          }
          

          查看 Chris Banes 的这些幻灯片:Becoming a master window fitter

          编辑:如果您在导航栏后面浮动的内容有问题,请使用

          // using Insetter
          binding.yourViewHere.applySystemWindowInsetsToPadding(bottom = true)
          

          【讨论】:

          • 我觉得你也可以使用支持库WindowCompat.setDecorFitsSystemWindows(window, false)
          【解决方案12】:

          分为三个步骤:

          1)只需将此代码段用于您的 OnCreate 方法

            // FullScreen
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, 
            WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
          

          如果您正在处理 Fragment,则应将此代码段放入 Activity 的 OnCreate 方法中。

          2) 一定要在 /res/values-v21/styles.xml 中也设置透明度:

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

          或者您可以通过编程方式设置透明度:

          getWindow().setStatusBarColor(Color.TRANSPARENT);
          

          3)无论如何你应该在styles.xml中添加代码段

          <item name="android:windowTranslucentStatus">true</item>
          

          注意:此方法仅适用于 API 21 及更高版本。

          【讨论】:

          • 如果用户只想透明特定活动,这将是一个糟糕的解决方案
          • @famfamfam 对于特定活动,您可以设置特定主题并在该主题中添加此属性
          【解决方案13】:

          在您的 XML 中使用此代码,您将能够在您的活动中看到时间栏:

          <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:app="http://schemas.android.com/apk/res-auto"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:fitsSystemWindows="true">
          

          【讨论】:

            【解决方案14】:

            我发现摆弄 style.xml 和活动太麻烦,因此创建了一个通用实用程序方法,它具有以下选项集

            Java

            Window window = getWindow();
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
            window.setStatusBarColor(Color.TRANSPARENT);
            

            Kotlin DSL

            activity.window.apply {
                clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
                addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
                decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                statusBarColor = Color.TRANSPARENT
            }
            

            这就是实现透明状态栏的全部内容。希望这会有所帮助。

            【讨论】:

              【解决方案15】:

              这对我有用:

              <item name="android:statusBarColor">@android:color/transparent</item>
              <item name="android:navigationBarColor">@android:color/transparent</item>
              <item name="android:windowTranslucentStatus">false</item>
              <item name="android:windowTranslucentNavigation">false</item>
              

              【讨论】:

                【解决方案16】:

                试试下面的代码:

                private static void setStatusBarTransparent(Activity activity) {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
                        activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                        activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
                        activity.getWindow(). setStatusBarColor(Color.TRANSPARENT);
                    } else {
                        activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                    }
                }
                

                【讨论】:

                  【解决方案17】:
                  <style name="Theme.Transparent" parent="Theme.AppCompat.Light.NoActionBar">
                      <item name="android:windowIsTranslucent">true</item>
                      <item name="android:windowTranslucentStatus">true</item>
                      <item name="android:windowTranslucentNavigation">true</item>
                      <item name="android:windowBackground">@android:color/transparent</item>
                  </style>
                  

                  【讨论】:

                    【解决方案18】:

                    我刚刚找到它here

                    因为已经过了 6 年,而默认的 minSDKAPI 是 21 (Lollipop) *CMIIW。这是我总结透明状态栏而不与导航按钮重叠的方法:

                    fun setStatusBarTransparent(activity: Activity, view: View) {
                        activity.apply {
                            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
                            window.statusBarColor = ContextCompat.getColor(this, R.color.transparent)
                            WindowCompat.setDecorFitsSystemWindows(window, false)
                            ViewCompat.setOnApplyWindowInsetsListener(view) { root, windowInset ->
                                val inset = windowInset.getInsets(WindowInsetsCompat.Type.systemBars())
                                root.updateLayoutParams<ViewGroup.MarginLayoutParams> {
                                    leftMargin = inset.left
                                    bottomMargin = inset.bottom
                                    rightMargin = inset.right
                                }
                                WindowInsetsCompat.CONSUMED
                            }
                        }
                    }
                    

                    我将该函数放在名为UiUtilsObject 类中,所以当我在我的活动中调用该函数时(我也使用视图绑定)。它看起来像这样:

                    override fun onCreate(savedInstanceState: Bundle?) {
                        super.onCreate(savedInstanceState)
                        ...
                        UiUtils.setStatusBarTransparent(this, bind.root)
                        ...
                    }
                    

                    希望我的回答能帮到你们:)

                    【讨论】:

                      【解决方案19】:

                      这是我经过大量搜索后找到的简单方法。

                      第 1 步

                      在你的主题中放这个项目

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

                      第 2 步

                      在主活动中

                      WindowCompat.setDecorFitsSystemWindows(window, false)
                      

                      如果您使用了 BottomNavigationBar,则非常重要

                      在某些 API 30+ 的设备中,如果在您的应用程序中使用它,您会发现系统导航栏与底部导航栏重叠。

                      这是解决这个问题的。

                        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
                              }
                      
                          }
                      

                      【讨论】:

                        【解决方案20】:

                        只需进入MainActivity.java


                        protected void onCreate(Bundle savedInstanceState) {
                                super.onCreate(savedInstanceState);
                        
                                Window g = getWindow();
                                g.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
                        
                                setContentView(R.layout.activity_main);
                        
                            }
                        

                        【讨论】:

                          【解决方案21】:

                          在我的情况下,我根本不调用“onCreate”(它是一个反应原生应用程序,这也可以通过使用 react-native StatusBar 组件来修复),也可以使用这个:

                          override fun onStart() {
                                  super.onStart()
                                  window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                                  window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
                                  window.statusBarColor = Color.TRANSPARENT
                          }
                          

                          【讨论】:

                            【解决方案22】:

                            虽然上述所有答案都围绕着相同的基本思想,但您可以使用上述示例之一使其与简单布局一起使用。但是,我想在使用滑动“全屏”(标签栏旁边)片段导航时更改背景颜色,并保持常规导航、标签和操作栏。

                            仔细阅读an article by Anton Hadutski后,我更好地了解了这是怎么回事。

                            我有DrawerLayoutConstraintLayout(即容器),其中有Toolbar,包括主要片段和BottomNavigationView

                            DrawerLayout 设置为将fitsSystemWindows 设置为true 是不够的,您需要同时设置DrawerLayoutConstraintLayout。假设状态栏是透明的,现在状态栏颜色和ConstraintLayout的背景颜色一样。

                            但是,包含的片段仍然插入了状态栏,因此在 with 顶部设置另一个“全屏”片段的动画不会改变状态栏的颜色。

                            引用文章中的一段代码到ActivityonCreate

                            ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.container)) { view, insets ->
                                    insets.replaceSystemWindowInsets(
                                            insets.systemWindowInsetLeft,
                                            0,
                                            insets.systemWindowInsetRight,
                                            insets.systemWindowInsetBottom
                                    )
                                }
                            

                            一切都很好,除了现在Toolbar 没有解决状态栏高度。更多参考这篇文章,我们有一个完整的解决方案:

                            val toolbar = findViewById<Toolbar>(R.id.my_toolbar)
                                ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.container)) { view, insets ->
                                    val params = toolbar.layoutParams as ViewGroup.MarginLayoutParams
                                    params.topMargin = insets.systemWindowInsetTop
                                    toolbar.layoutParams = params
                                    insets.replaceSystemWindowInsets(
                                            insets.systemWindowInsetLeft,
                                            0,
                                            insets.systemWindowInsetRight,
                                            insets.systemWindowInsetBottom
                                    )
                                }
                            

                            main_activity.xml(请注意Toolbar中的marginTop是为了预览,会被代码代替):

                            <?xml version="1.0" encoding="utf-8"?>
                                <androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
                                    xmlns:app="http://schemas.android.com/apk/res-auto"
                                    android:id="@+id/drawer_layout"
                                    android:layout_width="match_parent"
                                    android:layout_height="match_parent"
                                    android:fitsSystemWindows="true"
                                    >
                            
                                <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
                                    xmlns:app="http://schemas.android.com/apk/res-auto"
                                    xmlns:tools="http://schemas.android.com/tools"
                                    android:id="@+id/container"
                                    android:layout_width="match_parent"
                                    android:layout_height="match_parent"
                                    android:background="@color/green"
                                    android:fitsSystemWindows="true"
                                    tools:context=".MainActivity">
                            
                                    <androidx.appcompat.widget.Toolbar
                                        android:id="@+id/my_toolbar"
                                        android:layout_width="match_parent"
                                        android:layout_height="?attr/actionBarSize"
                                        app:layout_constraintTop_toTopOf="@id/container"
                                        android:layout_marginTop="26dp" 
                                        android:background="@android:color/transparent"
                                        ...>
                                        ...
                                    </androidx.appcompat.widget.Toolbar>
                            
                                    <include layout="@layout/content_main" />
                                    ...
                                </androidx.constraintlayout.widget.ConstraintLayout>
                                ...
                            </androidx.drawerlayout.widget.DrawerLayout>
                            

                            【讨论】:

                              【解决方案23】:

                              这是 Kotlin 扩展:

                              fun Activity.transparentStatusBar() {
                              
                                  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                              
                                      window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
                                      window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
                                      window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
                                      window.statusBarColor = Color.TRANSPARENT
                              
                                  } else
                                      window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
                              
                              }
                              

                              【讨论】:

                                【解决方案24】:

                                android:fitsSystemWindows="true" 仅适用于 v21。我们可以在主题 xml 或 LinearLayoutCoordinateLayout 等父布局中设置它。 对于 v21 以下,我们无法添加此标志。 请根据您的需要使用不同的style.xml 文件创建不同的值文件夹。

                                【讨论】:

                                  【解决方案25】:
                                   <item name="android:statusBarColor" tools:targetApi="lollipop">@android:color/transparent</item>
                                              <!--<item name="android:windowLightStatusBar" tools:targetApi="m">true</item>-->
                                  

                                  不要使用windowLightStatusBar,而是使用statusBarColor = @android:color/transparent

                                  【讨论】:

                                    【解决方案26】:

                                    在我的情况下,因为我有一个底部工具栏,所以在测试以前的解决方案时遇到了问题,android 系统按钮被我的底部菜单覆盖 我的解决方案是在活动中添加:

                                    protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

                                        // force full screen mode
                                        requestWindowFeature(Window.FEATURE_NO_TITLE);
                                        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                                                WindowManager.LayoutParams.FLAG_FULLSCREEN);
                                    
                                    
                                        setContentView(R.layout.main_activity_container);
                                    

                                    【讨论】:

                                      【解决方案27】:

                                      您可以使用以下代码。

                                      getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); 
                                      getWindow().setStatusBarColor(Color.TRANSPARENT);
                                      

                                      将此布局包含在您的主布局中。

                                      工具栏.xml

                                      <?xml version="1.0" encoding="utf-8"?>
                                      <androidx.appcompat.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
                                              android:id="@+id/toolbarNav"
                                              android:layout_width="match_parent"
                                              android:layout_height="wrap_content"
                                              android:background="@android:color/transparent"
                                              app:contentInsetEnd="0dp"
                                              app:contentInsetLeft="0dp"
                                              app:contentInsetRight="0dp"
                                              app:contentInsetStart="0dp">
                                      
                                              <RelativeLayout
                                                  android:id="@+id/rlBackImageLayout"
                                                  android:layout_width="match_parent"
                                                  android:layout_height="wrap_content"
                                                  android:background="@drawable/main_background2">  //add your color here
                                      
                                                  <LinearLayout
                                                      android:layout_width="match_parent"
                                                      android:layout_height="@dimen/_40sdp"
                                                      android:layout_marginTop="@dimen/_16sdp"
                                                      android:orientation="horizontal">
                                      
                                                      <ImageView
                                                          android:id="@+id/toolbarIcon"
                                                          android:layout_width="@dimen/_30sdp"
                                                          android:layout_height="@dimen/_30sdp"
                                                          android:layout_gravity="center"
                                                          android:layout_marginStart="@dimen/_10sdp"
                                                          android:padding="@dimen/_5sdp"
                                                          android:src="@drawable/nav_icon" />
                                      
                                                      <TextView
                                                          android:id="@+id/txtTitle"
                                                          android:layout_width="match_parent"
                                                          android:layout_height="match_parent"
                                                          android:layout_gravity="center"
                                                          android:layout_marginEnd="@dimen/_30sdp"
                                                          android:fontFamily="@font/muli_semibold"
                                                          android:gravity="center"
                                                          android:textColor="#fff"
                                                          android:textSize="@dimen/_14ssp"
                                                          android:textStyle="bold"
                                                          tools:text="test Data" />
                                      
                                                  </LinearLayout>
                                      
                                              </RelativeLayout>
                                      
                                          </androidx.appcompat.widget.Toolbar>
                                      

                                      注意:您可以将 SDP 和 SSP 分别替换为 dp 和 sp。

                                      【讨论】:

                                        【解决方案28】:

                                        这应该有效

                                        // 以Activity的onCreate()为例

                                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                                            Window w = getWindow();
                                            w.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
                                        }
                                        

                                        【讨论】:

                                          【解决方案29】:

                                          我在研究这个库时找到了答案: https://github.com/laobie/StatusBarUtil

                                          所以您需要将以下代码添加到您的活动中

                                          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                                              window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
                                              window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
                                              window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
                                              window.statusBarColor = Color.TRANSPARENT
                                          } else {
                                              window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
                                          }
                                          

                                          【讨论】:

                                            【解决方案30】:

                                            在 setContentView() 之前将这些行添加到您的 Activity 中

                                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                                                Window w = getWindow();
                                                w.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
                                            }
                                            

                                            将这两行添加到您的 AppTheme 中

                                            <item name="android:windowTranslucentStatus">true</item>
                                            <item name="android:windowTranslucentNavigation">true</item>
                                            

                                            最后一件事你的 minSdkVersion 必须是 b 19

                                            minSdkVersion 19
                                            

                                            【讨论】:

                                            • 如果用户只想为某些特定活动做一个不好的解决方案
                                            猜你喜欢
                                            • 2016-10-27
                                            • 2022-12-21
                                            • 2020-04-15
                                            • 1970-01-01
                                            • 2022-08-09
                                            • 2021-02-26
                                            • 1970-01-01
                                            • 2023-03-29
                                            相关资源
                                            最近更新 更多