Android完全透明的状态栏?

我已经搜索了文档,但只发现了这个: 链接。这是用来使条< em >半透明的< / em >?我要做的是使状态栏< em > < / em >完全透明(如下图所示),并使它向后兼容APK<19: enter image description here

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

我能做的是:

enter image description here

341487 次浏览

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

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

你的活动/容器布局,你希望有一个透明的状态栏需要这个属性集:

android:fitsSystemWindows="true"

通常不可能在pre-kitkat上执行此操作,看起来你可以但一些奇怪的代码使它如此

编辑:我推荐这个lib: 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);
}

没有其他主题是必要的,它产生如下内容:

enter image description here

在你的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">

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

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

 <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

在状态栏下绘制布局:

值/ styles.xml

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

values-v21 / styles.xml

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

使用已经照顾fitsSystemWindows参数的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>

结果:

< br > < p >截图: 截图 < / p >

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

getWindow().setFlags(
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
);
这仅适用于API级别>= 21。这对我很管用。 这是我的代码(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
}

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

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

下面是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 KitKat和以上(对于那些想要透明的状态栏和不操作导航栏,因为所有这些答案将透明导航栏太!)

最简单的实现方法:

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

就是这样!

试试下面的代码:

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

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

添加这2行到你的AppTheme

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

最后一件事你的思想sdkversion必须是19

minSdkVersion 19

这招对我很管用:

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

所有需要的是进入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);


}

有三个步骤:

只需将此代码段使用到OnCreate方法中

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

如果你正在使用Fragment,你应该把这个代码段放在你活动的OnCreate方法中。

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

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

或者你可以通过编程来设置透明度:

getWindow().setStatusBarColor(Color.TRANSPARENT);

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

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

注意:此方法只适用于API 21及以上。

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

protected void onCreate(Bundle savedInstanceState) { super.onCreate (savedInstanceState); < / p >

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

您可以使用下面的代码。

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

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

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

注:可以用dp代替SDP,用sp代替SSP。

在我的情况下,我不叫在所有“onCreate”(它的反应本机应用程序,这可以修复也通过使用反应本机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
}

你可以使用下面的代码使状态栏透明。 见图片红色高亮,帮助您识别使用下面的代码

< img src = " https://i.stack.imgur.com/wOgJi.png " alt = " 1]”>

你的android应用程序的Kotlin代码片段

步骤: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
}

步骤2:你需要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代码片段:

步骤1:主活动代码

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

步骤2: 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);
}
我在调查这个库时找到了答案: https://github.com/laobie/StatusBarUtil < / p >

因此,您需要将以下代码添加到您的活动

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

虽然上面所有的答案都围绕着相同的基本思想,但你可以使用上面的一个例子来实现简单的布局。然而,我想改变背景的颜色,同时使用滑动的“全屏”(标签栏除外)片段导航,并保持常规的导航,标签和操作栏。

在仔细阅读Anton Hadutski的一篇文章之后,我更好地理解了发生了什么。

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

DrawerLayout中的fitsSystemWindows设置为true是不够的,你需要同时设置DrawerLayoutConstraintLayout。假设状态栏是透明的,状态栏的颜色现在与ConstraintLayout的背景颜色相同。

然而,所包含的片段仍然有状态栏的嵌入,所以在上面动画另一个“全屏”片段并不会改变状态栏的颜色。

引用文章中的一段代码到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>

我发现摆弄styles.xml和activity太麻烦了,因此创建了一个通用的实用工具方法,它有以下选项集

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

芬兰湾的科特林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
}

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

这应该可以

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

这是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)


}

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

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

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

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

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

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

你可以从开发文档。中了解更多,我也建议阅读博客文章。

芬兰湾的科特林代码:

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

检查我的另一个答案在这里

下面的代码将使你的状态栏和导航栏透明(注意,这将使你的布局成为像游戏中使用的布局一样的全屏布局):

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

要了解更多,请访问链接。

API >23昼/夜支持你可以使用下面的扩展。要理解的重要部分是android:fitsSystemWindows="true"使用填充来在嵌入内移动(就像你使用工具栏一样)。因此,将它放在根布局中是没有意义的(除了DrawerLayout, CoordinatorLayout,…它们使用自己的实现)。

enter image description here

<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的这些幻灯片:成为窗户安装大师

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

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

下面的代码将创建一个完全透明的状态栏:

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

此解决方案适用于那些希望拥有完全透明的状态栏并且不受NavigationBar影响的人。令人难以置信的是,这听起来如此简单,以至于导致包括我在内的不止一个人头疼。

这就是我所说的最终结果

RESULT

我们将只需要两个函数,我建议在我们的活动的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
}
}

第二个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()
}
}

最终代码看起来像这样:

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

你可以在下面的帖子中找到更详细的解释

我还在这些概念工作的地方留下了测试项目

如果你使用的是React Native,那么其他帖子就不起作用了。React有自己的处理方法。

来自react-native<StatusBar translucent backgroundColor="transparent" />是正确的方法,多亏了这篇文章,这将覆盖App中的android设置。

然而,有两件事需要知道:

  1. 如果你从react-native-elements中使用<Header />组件,它已经包含了<StatusBar />,使用它的statusBarProps代替。
  2. 如果你正在使用WIX react-native-navigation,它们有一个单独的方法来处理状态栏,参考。他们说它与React Native不兼容,然而,看起来他们一起工作对我来说很好。

我刚刚发现它在这里

因为它已经经过了6年,默认的minSDKAPI是21(棒棒糖)*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
topMargin = 0
}
WindowInsetsCompat.CONSUMED
}
}
}

要再次显示状态栏只需要做一些更改:

fun setStatusBarShown(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())
val inset1 = windowInset.getInsets(WindowInsetsCompat.Type.statusBars())
root.updateLayoutParams<ViewGroup.MarginLayoutParams> {
leftMargin = inset.left
bottomMargin = inset.bottom
topMargin = inset1.top
rightMargin = inset.right
}
WindowInsetsCompat.CONSUMED
}
}
}

我把这个函数放在名为UiUtilsObject类中,因此当我在活动中调用该函数时(我也使用了视图绑定)。它看起来是这样的:

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

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

这是一个简单的方法,我找到了很多搜索。

步骤1

在你的主题里放这个项目

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

步骤2

主要活动

WindowCompat.setDecorFitsSystemWindows(window, false)

非常重要,如果你使用底部导航栏

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

这就解决了这个问题。

  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
}


}

2022年最优雅的方案:

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

它只是移除statusBar的颜色!

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

enter image description here

这招对我管用,希望对你也管用

要实现完全透明的状态栏: 首先将themes.xml中的自定义主题设置为

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

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

芬兰湾的科特林:

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
}

用于谷歌的最后一次更新。这是我的代码。这将是透明的状态栏和导航栏: 将您的主题更改为:

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

然后在layout (file xml)中:添加2个属性point_top和point_bottom来确定应用程序其他组件的边距值的位置:

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

然后在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)
}

希望这对大家有所帮助。