简体   繁体   English

Android 完全透明状态栏?

[英]Android Completely transparent Status Bar?

I've searched the documentation but only found this:Link .我搜索了文档,但只找到了这个:Link Which is used to make the bar translucent ?哪个是用来使酒吧半透明的? What I'm trying to do is to make the status bar completely transparent (as shown in the image below) and make it backwards compatible for APK<19:我要做的是使状态栏完全透明(如下图所示)并使其向后兼容 APK<19:在此处输入图像描述

My styles.xml:我的 styles.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>

What I was able to do:我能做的:

在此处输入图像描述

All you need to do is set these properties in your theme:您需要做的就是在您的主题中设置这些属性:

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

Your activity / container layout you wish to have a transparent status bar needs this property set:您希望拥有透明状态栏的活动/容器布局需要此属性集:

android:fitsSystemWindows="true"

It is generally not possible to perform this for sure on pre-kitkat, looks like you can do it but some strange code makes it so .通常不可能在 pre-kitkat 上确定执行此操作,看起来您可以执行此操作, 但一些奇怪的代码使其如此

EDIT: I would recommend this lib: https://github.com/jgilfelt/SystemBarTint for lots of pre-lollipop status bar color control.编辑:我会推荐这个库: https ://github.com/jgilfelt/SystemBarTint 用于大量的棒棒糖前状态栏颜色控制。

Well after much deliberation I've learned that the answer to totally disabling the translucency or any color placed on the status bar and navigation bar for lollipop is to set this flag on the window:经过深思熟虑,我了解到完全禁用棒棒糖状态栏和导航栏上的半透明或任何颜色的答案是在窗口上设置此标志:

// 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);
}

No other theme-ing is necessary, it produces something like this:不需要其他主题,它会产生如下内容:

在此处输入图像描述

You Can Use Below Code To Make Status Bar Transparent.您可以使用下面的代码使状态栏透明。 See Images With red highlight which helps you to identify use of Below code查看带有红色突出显示的图像,可帮助您识别以下代码的使用

1]

Kotlin code snippet for your android app您的 Android 应用程序的 Kotlin 代码片段

Step:1 Write down code in On create Method Step: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
}

Step2: You Need SetWindowFlag method which describe in Below code. Step2:您需要下面代码中描述的 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
}

Java code snippet for your android app:您的 android 应用程序的 Java 代码片段:

Step1: Main Activity Code Step1:主要活动代码

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

Step2: SetWindowFlag Method Step2: 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);
}

Just add this line of code to your main java file:只需将这行代码添加到您的主 java 文件中:

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

Works for Android KitKat and above (For those who want to transparent the status bar and don't manipulate the NavigationBar, because all of these answers will transparent the NavigationBar too!)适用于 Android KitKat 及更高版本(对于那些想要透明状态栏且不操纵 NavigationBar 的人,因为所有这些答案也会使 NavigationBar 透明!)

The easiest way to achieve it:实现它的最简单方法:

Put these 3 lines of code in the styles.xml (v19) -> if you don't know how to have this (v19), just write them in your default styles.xml and then use alt + enter to automatically create it:将这 3 行代码放入styles.xml (v19) -> 如果您不知道如何拥有它 (v19),只需将它们写入您的默认styles.xml ,然后使用alt + enter自动创建它:

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

And now, go to your MainActivity Class and put this Method out of onCreate in the class:现在,转到您的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);
}

Then put this code in the onCreate method of the Activity:然后把这段代码放到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);
    }

That's it!而已!

You can use the external library StatusBarUtil :您可以使用外部库StatusBarUtil

Add to your module level build.gradle :添加到您的模块级别build.gradle

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

Then you can use the following util for an Activity to make the status bar transparent:然后,您可以对 Activity 使用以下 util 使状态栏透明:

StatusBarUtil.setTransparent(Activity activity)

Example:例子:

Lollipop 和 KitKat 上的透明状态栏

Completely Transparent StatusBar and NavigationBar完全透明的状态栏和导航栏

@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);
}

To draw your layout under statusbar:在状态栏下绘制布局:

values/styles.xml值/样式.xml

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

values-v21/styles.xml值-v21/styles.xml

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

Use CoordinatorLayout/DrawerLayout which already take care of the fitsSystemWindows parameter or create your own layout to like this:使用 CoordinatorLayout/DrawerLayout 已经处理了 fitSystemWindows 参数或创建自己的布局,如下所示:

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

Result:结果:

Screenshot:截屏:
截屏

Simple and crisp and works with almost all use cases (for API level 16 and above):简单明了,适用于几乎所有用例(API 级别 16 及以上):

  1. Use the following tag in your app theme to make the status bar transparent:在您的应用主题中使用以下标签使状态栏透明:

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

  2. And then use this code in your activity's onCreate method.然后在您的活动的 onCreate 方法中使用此代码。

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

That's all you need to do ;)这就是你需要做的一切;)

You can learn more from the developer documentation.您可以从 开发人员文档中了解更多信息。 I'd also recommend reading this blog post.我还建议阅读这篇博文。

KOTLIN CODE :科特林代码

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

Check my another answer here在这里查看我的另一个答案

Here is a extension in kotlin that do the trick:这是 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
    }
}

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

THERE ARE THREE STEPS:有三个步骤:

1) Just use this code segment into your OnCreate method 1)只需将此代码段用于您的 OnCreate 方法

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

If you're working on Fragment, you should put this code segment in your activity's OnCreate method.如果您正在处理 Fragment,则应将此代码段放在活动的 OnCreate 方法中。

2) Be sure to also set the transparency in /res/values-v21/styles.xml: 2)一定要在 /res/values-v21/styles.xml 中设置透明度:

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

Or you can set the transparency programmatically:或者您可以以编程方式设置透明度:

getWindow().setStatusBarColor(Color.TRANSPARENT);

3) In anyway you should add the code segment in styles.xml 3)无论如何你应该在styles.xml中添加代码段

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

NOTE: This method just works on API 21 and above.注意:此方法仅适用于 API 21 及更高版本。

For API > 23 with Day/Night support you can use the extension below.对于具有日/夜支持的 API > 23,您可以使用下面的扩展。 Important part to understand is that android:fitsSystemWindows="true" uses padding to move within insets (like you would with a Toolbar).要理解的重要部分是android:fitsSystemWindows="true"使用填充在插图内移动(就像使用工具栏一样)。 Therefore it does not make sense to place it at your root layout (except DrawerLayout, CoordinatorLayout, ... these use their own implementation).因此,将其放置在您的根布局中是没有意义的(除了 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)
    }
}

Then call it like so:然后像这样调用它:

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

Check these slides by Chris Banes: Becoming a master window fitter查看 Chris Banes 的这些幻灯片:成为一名主要的窗户装配工

Edit: If you have problems with content floating behind your navigation bar, use编辑:如果您在导航栏后面浮动的内容有问题,请使用

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

I just found it here我刚在这里找到

Because it's already pass 6 years, and the default minSDKAPI is 21 (Lollipop) *CMIIW.因为已经过了 6 年,默认的 minSDKAPI 是 21 (Lollipop) *CMIIW。 Here is my way to conclude transparent status bar and not overlapping with navigation button:这是我总结透明状态栏而不与导航按钮重叠的方法:

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

I put that function inside Object class called UiUtils so when I call that function in my activity (I using View Binding too).我将该函数放在名为UiUtilsObject类中,因此当我在我的活动中调用该函数时(我也使用 View Binding)。 It'll look like this:它看起来像这样:

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

Hope my answer can help you guys :)希望我的回答能帮到大家:)

This is a simple way I found it after a lot of searches.这是我经过大量搜索后找到的一种简单方法。

Step 1步骤1

in your theme put this item在你的主题中放这个项目

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

Step 2第2步

In main Activity在主要活动中

WindowCompat.setDecorFitsSystemWindows(window, false)

Very Important if u used BottomNavigationBar如果您使用 BottomNavigationBar,则非常重要

in some devices, with API 30+ u will find system navigation bar overlap with bottom navigation bar if used it in your application.在某些设备中,如果在您的应用程序中使用 API 30+,您会发现系统导航栏与底部导航栏重叠。

this is solving for this problem.这是解决这个问题。

  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
        }

    }

Using this code in your XML, you will be able to see time bar in your activity:在您的 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">

I found fiddling with styles.xml and activity to be too cumbersome hence created a common utility method which has below options set我发现摆弄 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科特林 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
}

And that's all it took to achieve transparent status bar.这就是实现透明状态栏所需的全部内容。 Hope this helps.希望这可以帮助。

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

Try the following code:试试下面的代码:

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

This worked for me:这对我有用:

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

it just removes the statusBar color!它只是删除了状态栏颜色!

window?.decorView?.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
window?.statusBarColor = Color.TRANSPARENT

在此处输入图像描述

It worked for me, hope it works for you too它对我有用,希望它也对你有用

You can also view my example with animated avatar and animated text 您还可以使用动画头像和动画文本查看我的示例

CollapsingAvatarToolbarSample 折叠化身工具栏示例

Read my post on Medium 阅读我在Medium上的帖子

So lets me to explaine how it works. 因此,让我解释一下它是如何工作的。 I created custom view implemented AppBarLayout.OnOffsetChangedListener . 我创建了实现AppBarLayout.OnOffsetChangedListener的自定义视图。 Inside HeadCollapsing Custom View i founded text and image view in AppBarLayout. 在HeadCollapsing自定义视图内部,我在AppBarLayout中创建了文本和图像视图。

class HeadCollapsing(context: Context, attrs: AttributeSet?) : 
 FrameLayout(context, attrs), AppBarLayout.OnOffsetChangedListener {

  private fun findViews() {
            appBarLayout = findParentAppBarLayout()

            avatarContainerView = findViewById(R.id.imgb_avatar_wrap)

            titleToolbarText =  findViewById<AppCompatTextView>(id)

        }

  private fun findParentAppBarLayout(): AppBarLayout {
    val parent = this.parent
    return parent as? AppBarLayout ?: if (parent.parent is AppBarLayout) {
        parent.parent as AppBarLayout
    } else {
        throw IllegalStateException("Must be inside an AppBarLayout")
    }
}

  ...

     override fun onOffsetChanged(appBarLayout: AppBarLayout, offset:Int) {
           ...
           //Calculate expanded percentage
           val expandedPercentage = 1 - -offset / maxOffset
           updateViews(expandedPercentage)
     }
}

Then change views via calculated percentage. 然后通过计算的百分比更改视图。 For example, how text view changing: 例如,文本视图如何更改:

         when {
                inversePercentage < ABROAD -> {
                    titleToolbarText?.visibility = View.VISIBLE
                    titleTolbarTextSingle?.visibility = View.INVISIBLE
                }

                inversePercentage > ABROAD -> {
                    titleToolbarText?.visibility = View.INVISIBLE
                    titleTolbarTextSingle?.visibility = View.VISIBLE
                    titleTolbarTextSingle?.let {
                        animateShowText(it)
                    }
                }
            }

To detect when need image collapse animate created Pair object 检测何时需要图像折叠为创建的Pair对象制作动画

private var cashCollapseState: kotlin.Pair<Int, Int>? = null

with states: TO_EXPANDED_STATE, TO_COLLAPSED_STATE, WAIT_FOR_SWITCH, SWITCHED 状态:TO_EXPANDED_STATE,TO_COLLAPSED_STATE,WAIT_FOR_SWITCH,SWITCHED

  companion object {
        const val ABROAD = 0.95f
        const val TO_EXPANDED_STATE = 0
        const val TO_COLLAPSED_STATE = 1
        const val WAIT_FOR_SWITCH = 0
        const val SWITCHED = 1
    }

then cretaed animation for avatar swith state: 然后为头像切换状态的渐变动画:

 when {
                cashCollapseState != null && cashCollapseState != state -> {
                    when (state.first) {
                        TO_EXPANDED_STATE -> {
                          // do calculates
                        }
                        TO_COLLAPSED_STATE -> {

                    ValueAnimator.ofFloat(avatarContainerView.translationX, translationX).apply {
                        addUpdateListener {
                            avatarContainerView.translationX = it.animatedValue as Float
                        }

                        duration = 350
                        (state.first == TO_COLLAPSED_STATE).apply {
                            if (this) interpolator = LinearInterpolator()
                        }
                        start()
                    }
                //SWITCH STATE CASE
                cashCollapseState = kotlin.Pair(state.first, SWITCHED)
            }

            else -> {
                cashCollapseState = kotlin.Pair(state.first, WAIT_FOR_SWITCH)
            }

All one need is to go into MainActivity.java只需进入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);

    }

in my case, i dont call at all "onCreate" (its a react native app and this can be fixes also by using the react-native StatusBar component) one can also use this:在我的情况下,我根本不调用“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
}

While all the answers above circulate around the same fundamental idea and you can get it to work with simple layouts using one of the examples above.虽然上面的所有答案都围绕着相同的基本思想,但您可以使用上面的示例之一让它与简单的布局一起工作。 However I wanted to change the color of the background while using sliding 'full screen' (tab bar aside) fragment navigation and maintain regular navigation, tab and action bars.但是,我想在使用滑动“全屏”(标签栏旁边)片段导航时更改背景颜色,并保持常规导航、标签和操作栏。

After reading carefully an article by Anton Hadutski I had better understanding what is going on.在仔细阅读了 Anton Hadutski 的一篇文章后,我更好地理解了发生了什么。

I have DrawerLayout with ConstraintLayout (ie container) which has Toolbar , include for the main fragment and BottomNavigationView .我有DrawerLayoutConstraintLayout (即容器),它有Toolbar ,包括主要片段和BottomNavigationView

Setting DrawerLayout having fitsSystemWindows to true isn't sufficient, you need to set both DrawerLayout and ConstraintLayout .将具有DrawerLayoutfitsSystemWindows设置为 true 是不够的,您需要同时设置DrawerLayoutConstraintLayout Assuming transparent status bar, the status bar color is now the same as the background color of ConstraintLayout .假设透明状态栏,状态栏颜色现在与ConstraintLayout的背景颜色相同。

However, the included fragment has still the status bar inset, so animating another 'full screen' fragment on top of with doesn't change the color of the status bar.但是,包含的片段仍然具有状态栏插图,因此在 with 顶部设置另一个“全屏”片段的动画不会改变状态栏的颜色。

A bit of code from the referred article into Activity 's onCreate :参考文章中的一些代码进入ActivityonCreate

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

And all is good, except now the Toolbar doesn't address the status bar height.一切都很好,除了现在Toolbar没有解决状态栏的高度。 Some more referring to the article and we have a fully working solution:更多参考文章,我们有一个完整的解决方案:

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

The main_activity.xml (please note that marginTop in Toolbar is for preview purposes, it will be replaced by the code): 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>

Here is the Kotlin Extension:这是 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)

}

android:fitsSystemWindows="true" only work on v21. android:fitsSystemWindows="true"仅适用于 v21。 We can set it in theme xml or in parent layout like LinearLayout or in CoordinateLayout .我们可以在主题 xml 或父布局(如LinearLayoutCoordinateLayout )中设置它。 For below v21, We could not add this flag.对于 v21 以下,我们无法添加此标志。 Please create different values folder with different style.xml file as per your need.请根据您的需要使用不同的style.xml文件创建不同的值文件夹。

 <item name="android:statusBarColor" tools:targetApi="lollipop">@android:color/transparent</item>
            <!--<item name="android:windowLightStatusBar" tools:targetApi="m">true</item>-->

Dont use windowLightStatusBar use instead statusBarColor = @android:color/transparent不要使用windowLightStatusBar而是使用statusBarColor = @android:color/transparent

add these lines into your Activity before the setContentView()在 setContentView() 之前将这些行添加到您的活动中

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

add these 2 lines into your AppTheme将这两行添加到您的 AppTheme

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

and last thing your minSdkVersion must b 19最后一件事你的 minSdkVersion 必须 b 19

minSdkVersion 19

in my case as I've a bottom tool bar I had a problem when testing the previous solutions, the android system buttons are covered with my bottom menu my solution is to add within the activity:就我而言,因为我有一个底部工具栏,所以在测试以前的解决方案时遇到了问题,android 系统按钮被我的底部菜单覆盖,我的解决方案是在活动中添加:

protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); 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);

You can use this below code.您可以使用下面的代码。

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

Include this layout in your main layout.将此布局包含在您的主布局中。

toolbar.xml工具栏.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>

Note: You can replace SDP and SSP with dp and sp respectively.注意:您可以将 SDP 和 SSP 分别替换为 dp 和 sp。

This should work这应该工作

// In Activity's onCreate() for instance // 例如在 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);
}

The following code will make your status bar along with the navigation bar transparent (note that this will make your layout a full screen layout like the layouts used in games):以下代码将使您的状态栏和导航栏透明(请注意,这将使您的布局成为全屏布局,就像游戏中使用的布局一样):

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    if (hasFocus) {
        hideSystemUI();
    }
}

private void hideSystemUI() {
    // Enables sticky immersive mode.
    // For "lean back" mode, remove SYSTEM_UI_FLAG_IMMERSIVE_STICKY.
    // Or for regular immersive mode replace it with SYSTEM_UI_FLAG_IMMERSIVE
    View decorView = getWindow().getDecorView();
    decorView.setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                    // Set the content to appear under the system bars so that the
                    // content doesn't resize when the system bars hide and show.
                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    // Hide the nav bar and status bar
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_FULLSCREEN);
}

To learn more, visit this link.要了解更多信息,请访问链接。

The following code will create a fully transparent status bar:以下代码将创建一个完全透明的状态栏:

package com.demo;

import android.app.Activity;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

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

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

This solution is intended for those who want to have a completely transparent StatusBar and have the NavigationBar unaffected.此解决方案适用于希望拥有完全透明的StatusBar并且NavigationBar不受影响的用户。 Incredibly this sounds so simple that it has caused a headache to more than one, including me.令人难以置信的是,这听起来如此简单,以至于让包括我在内的不止一个人感到头疼。

This is the final result I'm talking about这就是我说的最终结果

RESULT结果

We are going to need only two functions, that I recommend to invoke in the OnCreate of our Activity, the first one is setStatusBar() , that is in charge of making transparent to the same one.我们将只需要两个函数,我建议在我们的 Activity 的 OnCreate 中调用它们,第一个是setStatusBar() ,它负责使同一个函数变得透明。

private fun setStatusBar() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    window.apply {
        clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
        addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            decorView.systemUiVisibility =
                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
        } else {
            decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
        }
        statusBarColor = Color.TRANSPARENT
    }
}

The second one, setMargins() is in charge of setting the margins corresponding to the views that are restricted with the top, since otherwise, these views would be seen below the StatusBar.第二个, setMargins()负责设置与顶部限制的视图相对应的边距,否则,这些视图将在状态栏下方看到。

private fun setMargins() {
    ViewCompat.setOnApplyWindowInsetsListener(
        findViewById(R.id.your_parent_view)
    ) { _, insets ->
        val view = findViewById<FrameLayout>(R.id.your_child_view)
        val params = view.layoutParams as ViewGroup.MarginLayoutParams
        params.setMargins(
            0,
            insets.systemWindowInsetTop,
            0,
            0
        )
        view.layoutParams = params
        insets.consumeSystemWindowInsets()
    }
}

The final code would look like:最终代码如下所示:

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.your_layout))
        setStatusBar()
        setMargins()
}

private fun setStatusBar() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    window.apply {
        clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
        addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            decorView.systemUiVisibility =
                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
        } else {
            decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
        }
        statusBarColor = Color.TRANSPARENT
    }
}

private fun setMargins() {
    ViewCompat.setOnApplyWindowInsetsListener(
        findViewById(R.id.your_parent_view)
    ) { _, insets ->
        val view = findViewById<FrameLayout>(R.id.your_child_view)
        val params = view.layoutParams as ViewGroup.MarginLayoutParams
        params.setMargins(
            0,
            insets.systemWindowInsetTop,
            0,
            0
        )
        view.layoutParams = params
        insets.consumeSystemWindowInsets()
    }
}

You can find a more detailed explanation of all this in the following Post您可以在以下帖子中找到所有这一切的更详细解释

I also leave a Test Project where these concepts are working.我还留下了一个测试项目,这些概念正在发挥作用。

If you are using React Native, other posts don't work.如果您使用的是 React Native,则其他帖子不起作用。 React has its own way to deal with it. React 有自己的处理方式。

<StatusBar translucent backgroundColor="transparent" /> from react-native is the way to go, thx to this post this will override android setting in App.来自react-native<StatusBar translucent backgroundColor="transparent" />是要走的路,感谢这篇文章,这将覆盖 App 中的 android 设置。

However, 2 things to know:但是,有两件事要知道:

  1. If you are using <Header /> component from react-native-elements , it already have <StatusBar /> included, using its statusBarProps instead.如果您正在使用react-native-elements中的<Header />组件,则它已经包含<StatusBar /> ,而是使用其statusBarProps
  2. If you are using WIX react-native-navigation, they have a separate way to dealing with the status bar, refer to this and this .如果您使用的是 WIX react-native-navigation,它们有单独的方式来处理状态栏,请参阅thisthis They said it is incompatible with React Native's , however, looks like they work well together for me.他们说它与 React Native 不兼容,但是,看起来它们对我来说很好用。

Most elegant solution in 2022: 2022 年最优雅的解决方案:

private fun hideStatusBar() {
    val windowInsetsController = ViewCompat.getWindowInsetsController(window.decorView) ?: return
    windowInsetsController.hide(WindowInsetsCompat.Type.statusBars())
}

To achieve completely transparent status bar: First make the custom theme in themes.xml as实现状态栏完全透明:首先在themes.xml中自定义主题为

 <style name="QuiloThemeLight" parent="Theme.AppCompat.Light.NoActionBar">

Java: Java:

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

Kotlin: Kotlin:

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
    }

For the last update from google.对于谷歌的最后更新。 This is my code.这是我的代码。 This will transparent for statusbar and navigationbar: Change your theme to this:这将对状态栏和导航栏透明:将您的主题更改为:

 <style name="Theme.Pink" 
 parent="Theme.MaterialComponents.DayNight.NoActionBar">
    <!-- Primary brand color. -->
    <item name="colorPrimary">@color/pink_primary</item>
    <item name="colorPrimaryVariant">@color/pink_dark</item>
    <item name="colorOnPrimary">@color/black</item>
    <!-- Secondary brand color. -->
    <item name="colorSecondary">@color/pink_light</item>
    <item name="colorSecondaryVariant">@color/pink_primary</item>
    <item name="colorOnSecondary">@color/black</item>
    <item name="android:textColor">?attr/colorOnPrimary</item>
    <!-- Status bar color. -->
    <!-- Customize your theme here. -->
 //transparent statusbar
    <item name="android:windowTranslucentStatus">true</item>
    <item name="android:windowIsTranslucent">true</item>
//transparent navigationbar
    <item name="android:windowTranslucentNavigation">true</item> 
 </style>

Then in layout (file xml): Add 2 properties point_top and point_bottom to determine the position of the margin value of other components of the app:然后在layout(文件xml)中:添加2个属性point_top和point_bottom来确定app其他组件的margin值的position:

    <androidx.constraintlayout.widget.ConstraintLayout 
    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:background="@drawable/bg_activity">

    <TextView
        android:id="@+id/point_top"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    

    <TextView
        android:id="@+id/point_bottom"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />
   
       <.....>

   </androidx.constraintlayout.widget.ConstraintLayout>

Then in baseActivity or yourActivity: add this code in onCreate:然后在 baseActivity 或 yourActivity: 在 onCreate 中添加此代码:

 override fun onCreate(savedInstanceState: Bundle?) {
   
    super.onCreate(savedInstanceState)
    binding = setLayout()
    //set inset for view
    ViewCompat.setOnApplyWindowInsetsListener(binding.root) { _, insets ->
        val paramsTop =
            findViewById<TextView>(R.id.point_top).layoutParams as MarginLayoutParams
        paramsTop.setMargins(0, insets.getInsets(WindowInsetsCompat.Type.systemBars()).top, 0, 0)
        findViewById<TextView>(R.id.point_top).layoutParams = paramsTop
        val paramsBottom =
            findViewById<TextView>(R.id.point_bottom).layoutParams as MarginLayoutParams
        paramsBottom.setMargins(0, 0, 0, insets.getInsets(WindowInsetsCompat.Type.systemBars()).bottom)
        findViewById<TextView>(R.id.point_bottom).layoutParams = paramsBottom
        insets.consumeSystemWindowInsets()

    }

    setContentView(binding.root)
}

Hope this to help everyone.希望这对大家有所帮助。

This is only for API Level >= 21. It works for me.这仅适用于 API 级别 >= 21。它适用于我。 Here is my code (Kotlin)这是我的代码(Kotlin)

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        findViewById<View>(android.R.id.content).systemUiVisibility =
                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
}

I found the answer while I investigating this library: https://github.com/laobie/StatusBarUtil我在调查这个库时找到了答案: https ://github.com/laobie/StatusBarUtil

so you need to add following codes to your activity所以你需要在你的活动中添加以下代码

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM