166

In one of my Activities, I changed the Toolbar color using Palette. But on 5.0 devices using ActionBarActivity the status bar color is the color of my colorPrimaryDark in my activity theme so I have 2 very different colors and it does not look good.

I realize that in 5.0 you can use Window.setStatusBarColor() but ActionBarActivity does not have this.

so my question is in 5.0 how can I change the status bar color with ActionBarActivity?

4levels
  • 3,134
  • 1
  • 23
  • 22
tyczj
  • 71,600
  • 54
  • 194
  • 296
  • Have you tried to use SystemBarTint lib ?https://github.com/jgilfelt/SystemBarTint – Nikola Despotoski Nov 04 '14 at 22:39
  • Possible duplicate of [How to change the status bar color in android](https://stackoverflow.com/questions/22192291/how-to-change-the-status-bar-color-in-android) – DSoldo Oct 10 '17 at 08:43

11 Answers11

473

I'm not sure I understand the problem.

I you want to change the status bar color programmatically (and provided the device has Android 5.0) then you can use Window.setStatusBarColor(). It shouldn't make a difference whether the activity is derived from Activity or ActionBarActivity.

Just try doing:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    Window window = getWindow();
    window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
    window.setStatusBarColor(Color.BLUE);
}

Just tested this with ActionBarActivity and it works alright.


Note: Setting the FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS flag programmatically is not necessary if your values-v21 styles file has it set already, via:

    <item name="android:windowDrawsSystemBarBackgrounds">true</item>
matiash
  • 54,791
  • 16
  • 125
  • 154
66

There are various ways of changing the status bar color.

  1. Using the styles.xml. You can use the android:statusBarColor attribute to do this the easy but static way.

Note: You can also use this attribute with the Material theme.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="AppTheme" parent="AppTheme.Base">
        <item name="android:statusBarColor">@android:color/transparent</item>
    </style>
</resources>
  1. You can get it done dynamically using the setStatusBarColor(int) method in the Window class. But remember that this method is only available for API 21 or higher. So be sure to check that, or your app will surely crash in lower devices.

Here is a working example of this method.

if (Build.VERSION.SDK_INT >= 21) {
            Window window = getWindow();
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.setStatusBarColor(getResources().getColor(R.color.primaryDark));
}

where primaryDark is the 700 tint of the primary color I am using in my app. You can define this color in the colors.xml file.

starball
  • 20,030
  • 7
  • 43
  • 238
Aritra Roy
  • 15,355
  • 10
  • 73
  • 107
  • it looks like window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); is not needed - but this one worked for me – bkurzius Feb 10 '15 at 14:09
  • Any ideas why the programmatic version would work but the style version doesn't? – Andrew Nov 13 '15 at 04:26
  • In my case the activity's style had the flah translucent_status set, so without the window.clearFlags command it didn't work. So thank you for this! – BMacedo Dec 29 '16 at 15:02
  • Oh wow! This should be accepted answer, add `clearFlags` fix my issue – fanjavaid Dec 23 '17 at 10:02
9

I don't think the status bar color has been implemented in AppCompat yet. These are the attributes which are available:

    <!-- ============= -->
    <!-- Color palette -->
    <!-- ============= -->

    <!-- The primary branding color for the app. By default, this is the color applied to the
         action bar background. -->
    <attr name="colorPrimary" format="color" />

    <!-- Dark variant of the primary branding color. By default, this is the color applied to
         the status bar (via statusBarColor) and navigation bar (via navigationBarColor). -->
    <attr name="colorPrimaryDark" format="color" />

    <!-- Bright complement to the primary branding color. By default, this is the color applied
         to framework controls (via colorControlActivated). -->
    <attr name="colorAccent" format="color" />

    <!-- The color applied to framework controls in their normal state. -->
    <attr name="colorControlNormal" format="color" />

    <!-- The color applied to framework controls in their activated (ex. checked) state. -->
    <attr name="colorControlActivated" format="color" />

    <!-- The color applied to framework control highlights (ex. ripples, list selectors). -->
    <attr name="colorControlHighlight" format="color" />

    <!-- The color applied to framework buttons in their normal state. -->
    <attr name="colorButtonNormal" format="color" />

    <!-- The color applied to framework switch thumbs in their normal state. -->
    <attr name="colorSwitchThumbNormal" format="color" />

(From \sdk\extras\android\support\v7\appcompat\res\values\attrs.xml)

JstnPwll
  • 8,585
  • 2
  • 33
  • 56
8

Just paste this function in your Utils class where you keep your all other common functions.

fun Activity.changeStatusBarColor(color: Int, isLight: Boolean) {
    window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
    window.statusBarColor = color

    WindowInsetsControllerCompat(window, window.decorView).isAppearanceLightStatusBars = isLight
}
 

and use it from anywhere like this:

changeStatusBarColor(
        ContextCompat.getColor(
            context,
            R.color.black
        ), false
    )

Note that here I also have managed the dark and light status bar colors separately to manage out icon and text colors of status bar.

Kishan Solanki
  • 13,761
  • 4
  • 85
  • 82
3

[Kotlin version] I created this extension that also checks if the desired color has enough contrast to hide the System UI, like Battery Status Icon, Clock, etc, so we set the System UI white or black according to this.

fun Activity.coloredStatusBarMode(@ColorInt color: Int = Color.WHITE, lightSystemUI: Boolean? = null) {
    var flags: Int = window.decorView.systemUiVisibility // get current flags
    var systemLightUIFlag = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
    var setSystemUILight = lightSystemUI

    if (setSystemUILight == null) {
        // Automatically check if the desired status bar is dark or light
        setSystemUILight = ColorUtils.calculateLuminance(color) < 0.5
    }

    flags = if (setSystemUILight) {
        // Set System UI Light (Battery Status Icon, Clock, etc)
        removeFlag(flags, systemLightUIFlag)
    } else {
        // Set System UI Dark (Battery Status Icon, Clock, etc)
        addFlag(flags, systemLightUIFlag)
    }

    window.decorView.systemUiVisibility = flags
    window.statusBarColor = color
}

private fun containsFlag(flags: Int, flagToCheck: Int) = (flags and flagToCheck) != 0

private fun addFlag(flags: Int, flagToAdd: Int): Int {
    return if (!containsFlag(flags, flagToAdd)) {
        flags or flagToAdd
    } else {
        flags
    }
}

private fun removeFlag(flags: Int, flagToRemove: Int): Int {
    return if (containsFlag(flags, flagToRemove)) {
        flags and flagToRemove.inv()
    } else {
        flags
    }
}
2

Try this, I used this and it works very good with v21.

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light">
    <item name="colorPrimaryDark">@color/blue</item>
</style>
Manoj Kumar
  • 318
  • 4
  • 14
0

Thanks for above answers, with the help of those, after certain R&D for xamarin.android MVVMCross application, below worked

Flag specified for activity in method OnCreate

protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);
        this.Window.AddFlags(WindowManagerFlags.DrawsSystemBarBackgrounds);
    }

For each MvxActivity, Theme is mentioned as below

 [Activity(
    LaunchMode = LaunchMode.SingleTop,
    ScreenOrientation = ScreenOrientation.Portrait,
    Theme = "@style/Theme.Splash",
    Name = "MyView"
    )]

My SplashStyle.xml looks like as below

<?xml version="1.0" encoding="utf-8"?>
<resources> 
    <style name="Theme.Splash" parent="Theme.AppCompat.Light.NoActionBar">
          <item name="android:statusBarColor">@color/app_red</item>
          <item name="android:colorPrimaryDark">@color/app_red</item>
    </style>
 </resources>

And I have V7 appcompact referred.

0

Applying

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

in Theme.AppCompat.Light.DarkActionBar didn't worked for me. What did the trick is , giving colorPrimaryDark as usual along with android:colorPrimary in styles.xml

<item name="android:colorAccent">@color/color_primary</item>
<item name="android:colorPrimary">@color/color_primary</item>
<item name="android:colorPrimaryDark">@color/color_primary_dark</item>

and in setting

if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
                {
                    Window window = this.Window;
                    Window.AddFlags(WindowManagerFlags.DrawsSystemBarBackgrounds);
                }

didn't had to set statusbar color in code .

Annu
  • 449
  • 6
  • 18
0

This can be implemented if you're using Kotlin in Android:

window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.statusBarColor = Color.WHITE
Ramesh R
  • 7,009
  • 4
  • 25
  • 38
0

add this kotlin code in OnCreate() of Activity or Fragment :

  if (Build.VERSION.SDK_INT >= 21) {
            val window: Window = requireActivity().window
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
            window.statusBarColor = resources.getColor(R.color.very_light_pink)
        }
Sana Ebadi
  • 6,656
  • 2
  • 44
  • 44
0

API 30+ Version

2023 Update

import android.app.Activity
import android.view.WindowInsetsController
import androidx.annotation.ColorInt
import androidx.core.graphics.ColorUtils

/**
 * Sets the status bar color and adjusts its icons' appearance based on the given color or
 * an optional override.
 *
 * @param color The color to set on the status bar.
 * @param useLightContent Optionally override the automatic light content detection.
 * If `true`, icons and clock will be light; if `false`, they will be dark.
 */
fun Activity.changeStatusBarColor(@ColorInt color: Int, useLightContent: Boolean? = null) {
    // Access the insets controller to modify system UI appearance
    val insetsController = window.insetsController

    // Determine the appearance mode for the content (icons, clock, etc.)
    // based on the luminance of the provided color or the optional override.
    val shouldUseLightContent = useLightContent ?: (ColorUtils.calculateLuminance(color) < 0.5)

    if (shouldUseLightContent) {
        // If the content should be light, clear the APPEARANCE_LIGHT_STATUS_BARS flag
        insetsController?.setSystemBarsAppearance(
            0,
            WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS
        )
    } else {
        // If the content should be dark, set the APPEARANCE_LIGHT_STATUS_BARS flag
        insetsController?.setSystemBarsAppearance(
            WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS,
            WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS
        )
    }

    // Set the provided color to the status bar
    window.statusBarColor = color
}

Notes: This code works only for API 30 (R) and up. Based on @Julián Falcionelli answer and reworked with ChatGPT 4. Tested on API 33 (Tiramisu).

Erdal G.
  • 2,694
  • 2
  • 27
  • 37