如何在 android 中将状态栏背景设置为渐变色或可绘制对象

how to set status bar background as gradient color or a drawable in android

我想将状态栏背景设置为渐变主题,状态栏和操作栏的颜色也应该是相同的可绘制渐变,根据文档,我们可以在 API 级别 21 及以上通过使用

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

但我正在搜索

<item name="android:statusBarDrawable">@drawable/myDrawable</item>

我看过使用

的示例
 <item name="android:windowTranslucentStatus">false</item>
   <item name="android:windowTranslucentNavigation">false</item>

但在那种情况下状态栏和操作栏重叠(使用 fitSystemWindow =true 但仍然没有解决)也尝试使用 https://github.com/jgilfelt/SystemBarTint 这个库但仍然没有运气

提前致谢!!

对于一些想要将渐变颜色设置为状态栏背景的人,您可以在 setContentView()

之前在 activity 中使用以下方法

对于Java

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public static void setStatusBarGradiant(Activity activity) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        Window window = activity.getWindow();
        Drawable background = activity.getResources().getDrawable(R.drawable.gradient_theme);
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        
        window.setStatusBarColor(activity.getResources().getColor(android.R.color.transparent));
        window.setNavigationBarColor(activity.getResources().getColor(android.R.color.transparent));
        window.setBackgroundDrawable(background);
    }
}

对于 Kotlin

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
fun setStatusBarGradiant(activity: Activity) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        val window: Window = activity.window
        val background =ContextCompat.getDrawable(activity, R.drawable.gradient_theme)
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
        
        window.statusBarColor = ContextCompat.getColor(activity,android.R.color.transparent)
        window.navigationBarColor = ContextCompat.getColor(activity,android.R.color.transparent)
        window.setBackgroundDrawable(background)
    }
}

感谢大家的帮助

编辑

如果以上代码不起作用,请尝试将其添加到您的 styles.xml:

<style name="AppTheme.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
</style>

如果您想用您的视图覆盖状态栏,请使用 window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);

由于 getColor 已弃用且使用 kotlin 语言,因此扩展了 sushant 的答案。

@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
fun backGroundColor() {
    window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
    window.statusBarColor = ContextCompat.getColor(this, android.R.color.transparent)
    window.navigationBarColor = ContextCompat.getColor(this, android.R.color.transparent)
    window.setBackgroundDrawableResource(R.drawable.ic_drawable_vertical_background)
}

想法是使状态栏透明,并为整个设置背景window,这也会在相同的背景下覆盖状态栏。

步骤 1: 创建状态栏 class 如下所示

public class StatusBarView extends View
{
    private int mStatusBarHeight;

    public StatusBarView(Context context)
    {
        this(context, null);

    }

    public StatusBarView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
            setSystemUiVisibility(SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
        }
    }

    @Override
    public WindowInsets onApplyWindowInsets(WindowInsets insets)
    {
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
            mStatusBarHeight = insets.getSystemWindowInsetTop();
            return insets.consumeSystemWindowInsets();
        }
        return insets;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),mStatusBarHeight);
    }
}

第 2 步: 创建如下所示的可绘制渐变

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <gradient
        android:type="linear"
        android:angle="135"
        android:endColor="#F34D80"

        android:startColor="#FF5858"/><!--android:centerColor="#C12389"-->
</shape>

第 3 步: 创建如下布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="wrap_content"
    android:orientation="vertical">

    <YOURPACKAGENAME.StatusBarView
        android:id="@+id/status_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/toolbar_bg_gradient"/>

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:background="@drawable/toolbar_bg_gradient"
        android:elevation="0dp"
        android:minHeight="?attr/actionBarSize"
        app:contentInsetStartWithNavigation="0dp"
        app:popupTheme="@style/AppTheme.PopupOverlay"
        app:subtitleTextColor="@android:color/white"
        app:theme="@style/AppTheme.AppBarOverlay"
        app:titleTextColor="@android:color/white" />
</LinearLayout>

Step4: 为 activity

创建样式
<style name="AppTheme.NoActionBarMain" parent="Base.Theme.AppCompat.Light">
        <item name="windowActionBar">false</item>
        <item name="android:windowDisablePreview">true</item>
        <item name="windowNoTitle">true</item>
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="android:windowContentOverlay">@null</item>
        <item name="android:windowEnableSplitTouch">false</item>
        <item name="android:splitMotionEvents">false</item>
        <item name="android:windowDrawsSystemBarBackgrounds" tools:targetApi="lollipop">true</item>
        <item name="android:statusBarColor" tools:targetApi="lollipop">@android:color/transparent</item>
        <item name="android:colorForeground">@color/foreground_material_light</item>
        <item name="windowActionModeOverlay">true</item>
        <item name="actionModeStyle">@style/LywActionMode</item>
    </style>

<style name="LywActionMode" parent="Base.Widget.AppCompat.ActionMode">
        <item name="background">@color/colorPrimary</item>
        <item name="backgroundSplit">@color/colorPrimary</item>
    </style>

我用了这个link的答案 如果你想显示操作栏,我添加了下一个代码使其成为 透明背景

final ActionBar ab = getSupportActionBar();
    if (ab != null) {
        Drawable gradientBG = getResources().getDrawable( R.drawable.bg_transperant);
        ab.setBackgroundDrawable(gradientBG);
    }

然后在 bg_gradient.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
       <solid android:color="@android:color/transparent" />
</shape>

@sushant gosavi 的答案是正确的,但它不适用于 DrawerLayout,除非您在 DrawerLayout 中执行以下操作。

<android.support.v4.widget.DrawerLayout
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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="false"
tools:openDrawer="start">

<include
    layout="@layout/app_bar_navigation"
    android:fitsSystemWindows="true"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

<android.support.design.widget.NavigationView
    android:id="@+id/nav_view"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:fitsSystemWindows="true"
    app:headerLayout="@layout/nav_header_navigation"
    app:menu="@menu/activity_navigation_drawer" />

您必须在 DrawerLayout 中更改为 false android:fitsSystemWindows="false",并在子

中将其设置为 true

添加以下两行对我有帮助:

window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);

这里是没有任何 Java 代码的方法,

渐变可绘制文件drawable/bg_toolbar.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <gradient
        android:type="linear"
        android:angle="0"
        android:startColor="#11998e"
        android:endColor="#38ef7d" />
</shape>

将此添加到您的 values/style.xml

<item name="android:windowBackground">@drawable/bg_toolbar</item>
<item name="toolbarStyle">@style/Widget.Toolbar</item>
<item name="android:statusBarColor">#00000000</item>

为您的工具栏渐变创建一个新文件values/toolbar.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="Widget.Toolbar" parent="@style/Widget.AppCompat.Toolbar">
        <item name="contentInsetStart">0dp</item>
        <item name="android:background">@drawable/bg_toolbar</item>
    </style>
</resources> 

编辑: 在您的 Activity 布局文件中添加 background android:background="#ffffff"

我是这样解决的

<style name="AppTheme.Base" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowBackground">@drawable/backfull</item>
    <item name="android:windowActionBar">false</item>

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

</style>

<style name="AppTheme2" parent="AppTheme.Base">
    <item name="colorPrimary">@drawable/backfull</item>
    <item name="colorPrimaryDark">@android:color/white</item>>
    <item name="colorAccent">@android:color/black</item>
    <item name="colorButtonNormal">@android:color/white</item>
</style>

<style name="ToolbarTheme" parent="Widget.AppCompat.Toolbar">
    <item name="android:background">@drawable/backfull</item>
    <item name="background">@android:color/black</item>
    <item name="titleTextAppearance">@style/ToolbarTitleTheme</item>
    <item name="popupTheme">@style/ThemeOverlay.AppCompat.Dark.ActionBar</item>
    <item name="theme">@style/ThemeOverlay.AppCompat.Dark.ActionBar</item>
</style>

<style name="ToolbarTitleTheme">
    <item name="android:textColor">@android:color/holo_red_dark</item>
    <item name="android:textStyle">bold</item>
</style>

请看看这个:

Enter link description here

使用自定义工具 class 解决此问题

sushant goswami 提供的答案实际上工作正常,浪费一天后终于意识到状态栏颜色和渐变起始颜色在我的情况下都是相同的,在将渐变颜色更改为默认状态以外的其他颜色后条形颜色效果很好

在onCreate中添加这段代码

getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
getWindow().setStatusBarColor(Color.TRANSPARENT);
android.graphics.drawable.Drawable background = MainActivity.this.getResources().getDrawable(R.drawable.status);
getWindow().setBackgroundDrawable(background);

现在在 drawable 文件夹中添加一个名为 status 的文件并放入此代码

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item><!-- Edit hex colors as you like -->
<shape android:shape="rectangle" >
<gradient
android:angle="180"
android:endColor="#806AF8"
android:startColor="#F16EB5" />
</shape></item></layer-list>

Kotlin 版本。基于 sushant gosavi 的回答

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
fun setBackgroundDrawableResource(window: Window, @DrawableRes drawableRes: Int) {
    val context = window.context
    val backgroundDrawable = ContextCompat.getDrawable(context, drawableRes) ?: return
    val transparentColor = ContextCompat.getColor(context, android.R.color.transparent)
    window.apply {
        addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
        statusBarColor = transparentColor
        setBackgroundDrawable(backgroundDrawable)
    }
}