如何在android中将状态栏背景设置为渐变色或drawable

Posted

技术标签:

【中文标题】如何在android中将状态栏背景设置为渐变色或drawable【英文标题】:how to set status bar background as gradient color or a drawable in android 【发布时间】:2017-08-25 16:30:07 【问题描述】:

我想将状态栏背景设置为渐变主题,状态栏和操作栏颜色应该相同的渐变可绘制,根据文档,我们可以使用 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 这个库但仍然没有运气

提前致谢!

【问题讨论】:

【参考方案1】:

对于想要为状态栏背景设置渐变色的人,您可以在 setContentView() 之前在您的活动中使用以下方法

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

对于科特林

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

【讨论】:

这个答案不起作用。为了在状态栏中获得渐变效果,我们还需要在样式上做些什么吗? 告诉我你做了什么!如果低于 Build.VERSION_CODES.LOLLIPOP 表示 21 或低于 21,则可能会检查您的设备版本代码,如果是,则此功能不适用于该设备 我确实按照你说的那样实现了你的代码@Override protected void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setStatusBarGradiant(这个); setContentView(R.layout.activity_detail); 你是否在活动的 setContentView 方法之前调用了上述方法?向我们展示您的代码@VindhyaPratapSingh 不工作,在 api 29【参考方案2】:

由于不推荐使用 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)

这个想法是使状态栏透明并为整个窗口设置背景,这也将覆盖同一背景中的状态栏。

【讨论】:

【参考方案3】:

这里是如何在没有任何 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>

为您的工具栏 Gradient 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> 

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

【讨论】:

【参考方案4】:

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

【讨论】:

只需使用下面的行来获取可绘制的。 ContextCompat.getDrawable(this, R.drawable.status_bar_gradient)【参考方案5】:

请看这个:

Enter link description here

使用自定义的 util 类来解决这个问题

【讨论】:

非常感谢。此解决方案在 API 29 上完美运行,与我尝试了几天的解决方案不同。【参考方案6】:

@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_
android:layout_
android:fitsSystemWindows="false"
tools:openDrawer="start">

<include
    layout="@layout/app_bar_navigation"
    android:fitsSystemWindows="true"
    android:layout_
    android:layout_ />

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

您必须在DrawerLayout 中更改为false android:fitsSystemWindows="false" 并在childs 中将其设置为true

【讨论】:

【参考方案7】:

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

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

【讨论】:

这是发送工具栏向上(在状态栏下) @HamedJaliliani 那么如何在不移除导航栏的情况下向状态栏添加渐变背景色?【参考方案8】:

第一步:创建如下状态栏类

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>

第三步:创建如下布局

<?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_
    android:layout_
    android:orientation="vertical">

    <YOURPACKAGENAME.StatusBarView
        android:id="@+id/status_bar"
        android:layout_
        android:layout_
        android:background="@drawable/toolbar_bg_gradient"/>

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_
        android:layout_
        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>

第四步:为活动创建样式

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

【讨论】:

我应该将类(第 1 步)创建为单独的文件还是将该代码复制到我的 Activity 类中? 好的,明白了。 我应该这样做[创建一个新的 .xml 文件(布局)] 还是将该代码复制到我的 activity_main.xml 文件中? (第 3 步) @ArdaÇebi 您应该在那里复制该代码及其示例,您可以根据需要进行更改 真的,行不通。我一直在尝试不同的地方和不同的形式来插入代码(在找到真正的地方之后当然只是为了确保我可以修复它)。【参考方案9】:

我在这个链接上使用了答案 here. 如果你想显示操作栏,我添加了下一个代码使其透明背景

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>

【讨论】:

【参考方案10】:

我是这样解决的

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

【讨论】:

【参考方案11】:

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

【讨论】:

【参考方案12】:

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)
    

【讨论】:

以上是关于如何在android中将状态栏背景设置为渐变色或drawable的主要内容,如果未能解决你的问题,请参考以下文章

Android 实现渐变色状态栏

如何使用java设置LinearLayout背景为渐变色

iOS 设置字体为渐变色

在ios 7中将UI状态栏的背景颜色设置为黑色

android沉浸式状态栏变色状态栏透明状态栏修改状态栏颜色及透明

Android开发:隐藏标题|状态栏沉浸|状态栏字体变色(继承AppCompatActivity)