如何在安卓系统中改变状态栏的颜色?

565

3
只有在KitKat之后才有可能实现。@MarkBuikema - codercat
9
如Niels所建议,从v21开始有一个名为 android:statusBarColor 的主题属性。你可以简单地将其添加到 values-v21/styles.xml 中。 - Levite
@MarkBuikema 这跟root访问权限有什么关系! - Steve Moretz
请查看此答案(使状态栏为白色,图标为黑色)。链接:https://dev59.com/gV4c5IYBdhLWcg3wuMJ7#74375368 - Rumit Patel
32个回答

794

37
由于某些原因,colorPrimaryDark属性对我不起作用。已在模拟器v21上尝试。 - deviant
4
它是有效的,但你需要在模拟器上查看更改,而不是在布局预览中查看(因为它不会显示在那里)。 - Mightian
9
在API 18模拟器上,colorPrimaryDark 对我也没有生效。从与 AppCompat 相关的文章中可以看到:“在较旧的平台上,AppCompat 尽可能地模拟颜色主题。目前这仅限于为操作栏和某些小部件着色。” - Adam Johns
23
在状态栏中更改字体颜色怎么样?文档中没有提到这一点。 - SMBiggs
2
现在在 themes.xml 中,将使用 colorPrimaryVariant 替代 colorPrimaryDark - Reejesh PK
显示剩余4条评论

447

更新:

棒棒糖(Lollipop):

public abstract void setStatusBarColor (int color)

自 API level 21 起引入

安卓棒棒糖带来了改变应用程序状态栏颜色的功能,以便更深入的用户体验,并符合 Google 的 Material Design Guidelines

以下是示例代码,演示了如何使用新的 window.setStatusBarColor 方法来改变状态栏颜色,此方法在API level 21中被引入。

同时, 更改状态栏颜色还需要在窗口上设置两个附加标志; 需要添加 FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS 并清除 FLAG_TRANSLUCENT_STATUS 标志。

代码实现:

import android.view.Window;

...

Window window = activity.getWindow();

// clear FLAG_TRANSLUCENT_STATUS flag:
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

// add FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS flag to the window
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);

// finally change the color
window.setStatusBarColor(ContextCompat.getColor(activity,R.color.my_statusbar_color));

官方的开发者参考:setStatusBarColor(int)

示例:material-design-everywhere

Chris Banes博客- appcompat v21:面向pre-Lollipop设备的材料设计!

enter image description here

视图背景的transitionName将为android:status:background


3
有没有解决向后兼容性的方法? - AdamHurwitz
2
正如Niels的回答中所指出的那样:您还可以通过在values-v21/styles.xml文件中设置android:statusBarColor来配置状态栏颜色,详见http://www.androiddocs.com/training/material/theme.html,示例如下:<item name="android:statusBarColor">@color/primary_color</item> - JL West
9
我可以将状态栏的颜色更改为白色,但我无法看到诸如电池之类的通知图标,该怎么解决? - MNFS
@codercat:请指导一下如何配置系统栏和导航栏以获得沉浸式体验。https://stackoverflow.com/questions/69567649/how-to-configure-the-system-bar-and-navigation-bar-for-immersive-experience - SVK
请问如何撤销这个操作? - ericn

296
将此代码放置在您的values-v21/styles.xml中,以在Lollipop上启用此功能。
<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light">
        <item name="colorPrimary">@color/color_primary</item>
        <item name="colorPrimaryDark">@color/color_secondary</item>
        <item name="colorAccent">@color/color_accent</item>
        <item name="android:statusBarColor">@color/color_primary</item>
    </style>
</resources>

36
需要最低API 21。 - Roman
57
这可能是他建议将其放入values-v21/styles.xml中的原因;-) 看起来这是迄今为止最准确的答案!! - Levite
但是这仍然会标记一个警告!!? - Nihal Sharma
什么是兼容性的功能?状态栏。 - blackHawk
如果您想维护单个样式文件,可以添加“targeApi”属性。请参考我的答案 https://dev59.com/x2Eh5IYBdhLWcg3wpEtF#48565459 - Faisal Shaikh

61

针对Java开发者:

如@Niels所说,您需要将其放置在values-v21/styles.xml中:

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

如果您想要一个单独的styles.xml文件,请在tools:targetApi="lollipop"中添加:

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

针对 Kotlin 开发者:

window.statusBarColor = ContextCompat.getColor(this, R.color.color_name)

6
非常感谢“targetApi”。我不喜欢将我的主题分散在多个文件中。 :) - plexus

50

这是一种非常简便的方法,可以在没有任何库的情况下完成此操作: 如果操作系统版本不受支持-在4.4以下-则不会发生任何事情。 我执行以下步骤:

  1. 在我的xml文件中,我添加了以下View标签:
<View
        android:id="@+id/statusBarBackground"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
然后我写了这个方法:
 public void setStatusBarColor(View statusBar,int color){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
           Window w = getWindow();
           w.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
           //status bar height
           int actionBarHeight = getActionBarHeight();
           int statusBarHeight = getStatusBarHeight();
           //action bar height
           statusBar.getLayoutParams().height = actionBarHeight + statusBarHeight;
           statusBar.setBackgroundColor(color);
     }
}

同时您需要使用这两种方法来获取ActionBar和状态栏的高度:

public int getActionBarHeight() {
    int actionBarHeight = 0;
    TypedValue tv = new TypedValue();
    if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true))
    {
       actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics());
    }
    return actionBarHeight;
}

public int getStatusBarHeight() {
    int result = 0;
    int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
    if (resourceId > 0) {
        result = getResources().getDimensionPixelSize(resourceId);
    }
    return result;
}

如果您想设置状态栏颜色,唯一需要的就是这行代码:

setStatusBarColor(findViewById(R.id.statusBarBackground),getResources().getColor(android.R.color.white));

1
我应该把视图元素放在哪里?它应该在主布局的顶部吗? - Emil Reña Enriquez
是的,在你的xml文件中,在它的顶部。 - itzhar
注意:仅适用于Android >= 19 API。在我的情况下,我需要从16开始支持。 - Anton Kizema
setStatusBarColor(findViewById(android.R.id.statusBarBackground),getResources().getColor(android.R.color.white)); - AndroidLad

50
您可以使用以下简单的代码:

Kotlin中的一行代码:

window.statusBarColor = ContextCompat.getColor(this, R.color.colorName)

使用Java进行手动版本检查的原始答案:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    getWindow().setStatusBarColor(getResources().getColor(R.color.colorAccentDark_light, this.getTheme()));
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    getWindow().setStatusBarColor(getResources().getColor(R.color.colorAccentDark_light));
}

您可以使用ContextCompat进一步简化此过程。在Kotlin中,只需这样做:window.statusBarColor = ContextCompat.getColor(this, R.color.colorName) - sunadorer
我写这篇文章的时候还没有尝试过Kotlin。你为什么不编辑答案,然后我可以批准它 :) - Steve Moretz
好主意。我已经在答案中包含了我的建议,方便未来的访问者参考。 - sunadorer
状态栏颜色在Build.VERSION_CODES.M以上已更改。在Lollipop以下无法工作。 - Muhammed Haris
@MuhammedHaris,它确实有效。你使用的是Kotlin还是Java代码? - Steve Moretz

40

要更改上面棒棒糖的颜色,只需将以下内容添加到您的styles.xml文件中

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

但请记住,如果您想为状态栏使用浅色,请也添加这一行。

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

真是令人惊讶,竟然没有其他人觉得有必要提到windowLightStatusBar这一点。可以看出谁是复制粘贴的艺术家们。:-) 任何真正做过这个的人都会知道SDK文档中存在的明显漏洞。 - Robin Davies

32

嗯,Izhar的解决方案还可以,但我个人尽量避免编写像这样的代码:

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
//Do what you need for this SDK
};

但我也不喜欢重复代码。在你的回答中,我必须在所有活动中添加如下代码行:

setStatusBarColor(findViewById(R.id.statusBarBackground),getResources().getColor(android.R.color.white));

所以,我采用了Izhar的解决方案,并使用XML来获得相同的结果:创建一个StatusBar status_bar.xml的布局。

<View xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="@dimen/statusBarHeight"
     android:background="@color/primaryColorDark"
     android:elevation="@dimen/statusBarElevation">

注意高度和高程属性,这些将在下面的values、values-v19、values-v21中设置。

使用include,在main_activity.xml中添加此布局到您的活动布局中:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/Black" >

<include layout="@layout/status_bar"/>
<include android:id="@+id/app_bar" layout="@layout/app_bar"/>
//The rest of your layout       
</RelativeLayout>

为工具栏添加顶部边距属性:

<android.support.v7.widget.Toolbar 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="?android:attr/actionBarSize"
android:background="@color/primaryColor"
app:theme="@style/MyCustomToolBarTheme"
app:popupTheme="@style/ThemeOverlay.AppCompat.Dark"
android:elevation="@dimen/toolbarElevation"
android:layout_marginTop="@dimen/appBarTopMargin"
android:textDirection="ltr"
android:layoutDirection="ltr">

</android.support.v7.widget.Toolbar>

在您的appTheme style-v19.xml和styles-v21.xml中,添加windowTranslucent属性:

styles-v19.xml,v21:

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

最后,在你的dimens、dimens-v19和dimens-v21文件中,添加Toolbar的topMargin值以及statusBarHeight的高度: 低于KitKat版本的dimens.xml:

<resources>
<dimen name="toolbarElevation">4dp</dimen>
<dimen name="appBarTopMargin">0dp</dimen>
<dimen name="statusBarHeight">0dp</dimen>
</resources>

状态栏的高度始终为 24dp 在 Android 4.4 KitKat 及以上版本中使用 dimens-v19.xml:

<resources>
<dimen name="statusBarHeight">24dp</dimen>
<dimen name="appBarTopMargin">24dp</dimen>
</resources>

对于Lolipop,使用dimens-v21.xml文件,如果需要,只需添加elevation即可:

<resources>
<dimen name="statusBarElevation">4dp</dimen>
</resources>

这是Jellybean、KitKat和Lollipop的结果:

输入图像描述


所以,你没有把检查放在代码中,而是放在了XML中。你的解决方案将在Kitkat上运行,就像他得到的一样。 - android developer

26

只需在 res/values/styles.xml 中创建一个新的主题,其中更改“colorPrimaryDark”,这是状态栏的颜色:

<style name="AppTheme.GrayStatusBar" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="colorPrimaryDark">@color/colorGray</item>
</style>

AndroidManifest.xml 中修改活动主题为您想要的主题,然后在下一个活动中,通过选择原始主题可以将颜色改回原始颜色:

<activity
    android:name=".LoginActivity"
    android:theme="@style/AppTheme.GrayStatusBar" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

这就是你的 res/values/colors.xml 应该看起来的样子:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#c6d6f0</color>
    <color name="colorGray">#757575</color>
</resources>

5
我认为这是最简单但最清晰的解决方案。只需要简单地重写,无需具备最低21个API级别。值得得到更多赞。 - tahsinRupam
当在Nougat上运行并将API级别设置为19时,这并没有起作用。如果我在清单文件中的应用程序节点下设置android:theme,则可以正常工作。 - Johann

20

你可以使用此函数更改状态栏的颜色。它适用于安卓 L 版本(API 21及以上),需要一个颜色字符串,例如:"#ffffff"

private void changeStatusBarColor(String color){
    if (Build.VERSION.SDK_INT >= 21) {
        Window window = getWindow();
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        window.setStatusBarColor(Color.parseColor(color));
    }
}

嗨@Naga,我已在Android 7上测试过它,它可以工作! - sajad abbasi
嗨@Naga,我已在Android 9上进行了测试,一切正常! - sajad abbasi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接