Cambie el color de la barra de estado con AppCompat ActionBarActivity

146

En una de mis actividades, cambié el color de la barra de herramientas usando Palette. Pero en los dispositivos 5.0 que usan ActionBarActivityel status barcolor es el color de mi colorPrimaryDarktema en mi actividad, por lo que tengo 2 colores muy diferentes y no se ve bien.

Me doy cuenta de que en 5.0 puedes usar Window.setStatusBarColor()pero ActionBarActivityno tiene esto.

entonces mi pregunta es en 5.0 ¿cómo puedo cambiar el color de la barra de estado ActionBarActivity?

tyczj
fuente
¿Has intentado usar SystemBarTint lib? github.com/jgilfelt/SystemBarTint
Nikola Despotoski

Respuestas:

420

No estoy seguro de entender el problema.

Si desea cambiar el color de la barra de estado mediante programación (y siempre que el dispositivo tenga Android 5.0), puede usarlo Window.setStatusBarColor(). No debería hacer una diferencia si la actividad se deriva de Activityo ActionBarActivity.

Solo intenta hacer:

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

Acabo de probar esto ActionBarActivityy funciona bien.


Nota: FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDSNo es necesario configurar el indicador mediante programación si su values-v21archivo de estilos ya lo tiene configurado, a través de:

    <item name="android:windowDrawsSystemBarBackgrounds">true</item>
matiash
fuente
1
ah ok no estaba usandogetWindow()
tyczj 05 de
esto se bloqueará cuando el código LOLLIPOP no se encuentre en los androides antiguos. es mejor usar> = 21
code511788465541441
12
@ code578841441 En realidad, eso no debería suceder. Las constantes están en línea al compilar.
matiash
44
@ code578841441: Eso es porque estás compilando con un SDK anterior. Siempre debe esforzarse por compilar con el último SDK de Android, incluso si tiene restricciones de versión de API anteriores (es decir, minSdkVersiony / o targetSdkVersionatributos en el <uses-sdk ...>elemento).
dbm
3
También tuve que llamar a getWindow (). AddFlags (WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); para que funcione
Philipp E.
61

Hay varias formas de cambiar el color de la barra de estado.

1) Usando el styles.xml. Puede usar el atributo android: statusBarColor para hacer esto de manera fácil pero estática.

Nota: También puede usar este atributo con el tema Material.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="AppTheme" parent="AppTheme.Base">
        <item name="android:statusBarColor">@android:color/transparent</item>
    </style>
</resources>

2) Puede hacerlo dinámicamente utilizando el método setStatusBarColor (int) en la clase Window. Pero recuerde que este método solo está disponible para API 21 o superior. Así que asegúrese de verificar eso, o su aplicación seguramente se bloqueará en dispositivos inferiores.

Aquí hay un ejemplo de trabajo de este método.

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

donde primaryDark es el tinte 700 del color primario que estoy usando en mi aplicación. Puede definir este color en el archivo colors.xml.

Pruébalo y avísame si tienes alguna pregunta. Espero eso ayude.

Aritra Roy
fuente
se parece a window.clearFlags (WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); no es necesario, pero este funcionó para mí
bkurzius
¿Alguna idea de por qué la versión programática funcionaría pero la versión de estilo no?
Andrew
En mi caso, el estilo de la actividad tenía el conjunto flah translucent_status, por lo que sin el comando window.clearFlags no funcionó. ¡Así que gracias por esto!
BMacedo
¡Oh wow! Esta debe ser la respuesta aceptada, añadir clearFlagsarreglar mi problema
fanjavaid
9

No creo que el color de la barra de estado se haya implementado en AppCompat todavía. Estos son los atributos que están disponibles:

    <!-- ============= -->
    <!-- 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" />

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

JstnPwll
fuente
1
Es posible que nunca se implemente en AppCompat si las versiones anteriores del sistema operativo no ofrecen ninguna capacidad para modificar la barra de estado.
TheIT
2
<attr name = "colorPrimaryDark" format = "color" /> <! - Variante oscura del color de marca principal. De forma predeterminada, este es el color aplicado a la barra de estado (a través de statusBarColor) y a la barra de navegación (a través de navigationBarColor). ->
Soheil Setayeshi
3

Prueba esto, lo usé y funciona muy bien con v21.

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light">
    <item name="colorPrimaryDark">@color/blue</item>
</style>
Manoj Kumar
fuente
1

Gracias por las respuestas anteriores, con la ayuda de aquellos, después de cierta I + D para la aplicación MVVMCross xamarin.android, a continuación funcionó

Indicador especificado para la actividad en el método OnCreate

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

Para cada MvxActivity, el tema se menciona a continuación

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

Mi SplashStyle.xml se ve a continuación

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

Y tengo V7 appcompact referido.

Pallavi
fuente
1

[Versión de Kotlin] Creé esta extensión que también comprueba si el color deseado tiene suficiente contraste para ocultar la IU del sistema, como el icono de estado de la batería, el reloj, etc., por lo que configuramos la IU del sistema en blanco o negro de acuerdo con esto.

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
    }
}
Julián Falcionelli
fuente
0

Aplicando

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

en Theme.AppCompat.Light.DarkActionBarno funcionó para mí. ¿Cuál fue el truco, dar colorPrimaryDarkcomo de costumbre junto con android:colorPrimaryen 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>

y en ambientación

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

no tuvo que establecer el color de la barra de estado en el código.

Annu
fuente