Material de Android: el color de la barra de estado no cambiará

Estoy desarrollando una aplicación simple para probar el diseño del material. Estoy usando com.android.support:appcompat-v7:21.0.0 y mi actividad se ve así:

 public class MyActivity extends ActionBarActivity { ... } 

El diseño se define como:

    

Ahora definí mi tema siguiendo las pautas materiales:

  @color/colorPrimary500 @color/colorPrimaryDark700  

Me gustaría cambiar el color de la barra de estado en pre Android 5 y configurarlo en colorPrimaryDark pero no puedo encontrar el camino. Intenté usar:

 getWindow().setStatusBarColor(..) 

pero el color de setStatusBar está disponible desde el nivel 21. ¿Por qué si defino un colorPrimaryDark en mi tema y uso de appcompact la barra de estado no cambia de color? Cualquiera puede ayudar?

La barra de estado es una ventana del sistema propiedad del sistema operativo. En los dispositivos Android anteriores a la 5.0, las aplicaciones no tienen permiso para alterar su color, por lo que la biblioteca de AppCompat no es compatible con versiones anteriores de la plataforma. Lo mejor que puede hacer AppCompat es proporcionar soporte para colorear el ActionBar y otros widgets UI comunes dentro de la aplicación.

Mientras colorea la barra de estado no es compatible <5.0, en 4.4 puede usar una solución para lograr un color más oscuro:

Haz que la barra de estado sea translúcida

 true 

Luego use la barra de herramientas de AppCompat para su barra de aplicaciones, asegurándose de que se ajuste a las ventanas del sistema:

  

Asegúrese de configurar su barra de herramientas como la barra de herramientas de su actividad:

 protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ... toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); 

La barra de herramientas se extiende debajo de la barra de estado, y la semi translucidez de la barra de estado hace que parezca un color secundario más oscuro. Si ese no es el color que desea, esta combinación le permite colocar una vista debajo de la barra de estado con el color de fondo que prefiera (aunque la barra de estado aún lo oscurece).

Una especie de solución de caso extremo debido a 4.4 solamente, pero ya está.

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); getWindow().setStatusBarColor(getResources().getColor(R.color.actionbar)); } 

Ponga este código en el método onCreate su actividad. Esto me ayudó.

Como otros también han mencionado, esto se puede resolver fácilmente agregando lo siguiente a onCreate () de la Actividad:

  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); getWindow().setStatusBarColor(ContextCompat.getColor(this, R.color.primary_dark)); } 

Sin embargo, el punto importante que quiero agregar aquí es que, en algunos casos, incluso lo anterior no cambia el color de la barra de estado. Por ejemplo, al usar la biblioteca MikePenz para Navigation Drawer, implícitamente reemplaza el color de la barra de estado, por lo que debe agregar manualmente lo siguiente para que funcione:

.withStatusBarColorRes (R.color.status_bar_color)

La coloración de la barra de estado no es compatible con AppCompat v7: 21.0.0.

De la publicación de blog de desarrolladores de Android

En las plataformas más antiguas, AppCompat emula la tonalidad del color siempre que sea posible. Por el momento, esto se limita a colorear la barra de acciones y algunos widgets.

Esto significa que la aplicación AppCompat lib solo coloreará barras de estado en Lollipop y más arriba.

Cambie a AppCompatActivity y agregue un paddingTop de 25 dp en la barra de herramientas y encienda

 true 

Luego, la barra de herramientas de la voluntad irá arriba

Esta solución establece el color de la barra de estado de Lollipop, Kitkat y algunos dispositivos pre Lollipop (Samsung y Sony). El SystemBarTintManager está administrando los dispositivos Kitkat;)

 @Override protected void onCreate( Bundle savedInstanceState ) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); hackStatusBarColor(this, R.color.primary_dark); } @SuppressLint("NewApi") @SuppressWarnings("deprecation") public static View hackStatusBarColor( final Activity act, final int colorResID ) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { try { if (act.getWindow() != null) { final ViewGroup vg = (ViewGroup) act.getWindow().getDecorView(); if (vg.getParent() == null && applyColoredStatusBar(act, colorResID)) { final View statusBar = new View(act); vg.post(new Runnable() { @Override public void run() { int statusBarHeight = (int) Math.ceil(25 * vg.getContext().getResources().getDisplayMetrics().density); statusBar.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, statusBarHeight)); statusBar.setBackgroundColor(act.getResources().getColor(colorResID)); statusBar.setId(13371337); vg.addView(statusBar, 0); } }); return statusBar; } } } catch (Exception e) { e.printStackTrace(); } } else if (act.getWindow() != null) { act.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); act.getWindow().setStatusBarColor(act.getResources().getColor(colorResID)); } return null; } private static boolean applyColoredStatusBar( Activity act, int colorResID ) { final Window window = act.getWindow(); final int flag; if (window != null) { View decor = window.getDecorView(); if (decor != null) { flag = resolveTransparentStatusBarFlag(act); if (flag != 0) { decor.setSystemUiVisibility(flag); return true; } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) { act.findViewById(android.R.id.content).setFitsSystemWindows(false); setTranslucentStatus(window, true); final SystemBarTintManager tintManager = new SystemBarTintManager(act); tintManager.setStatusBarTintEnabled(true); tintManager.setStatusBarTintColor(colorResID); } } } return false; } public static int resolveTransparentStatusBarFlag( Context ctx ) { String[] libs = ctx.getPackageManager().getSystemSharedLibraryNames(); String reflect = null; if (libs == null) return 0; final String SAMSUNG = "touchwiz"; final String SONY = "com.sonyericsson.navigationbar"; for (String lib : libs) { if (lib.equals(SAMSUNG)) { reflect = "SYSTEM_UI_FLAG_TRANSPARENT_BACKGROUND"; } else if (lib.startsWith(SONY)) { reflect = "SYSTEM_UI_FLAG_TRANSPARENT"; } } if (reflect == null) return 0; try { Field field = View.class.getField(reflect); if (field.getType() == Integer.TYPE) { return field.getInt(null); } } catch (Exception e) { } return 0; } @TargetApi(Build.VERSION_CODES.KITKAT) public static void setTranslucentStatus( Window win, boolean on ) { WindowManager.LayoutParams winParams = win.getAttributes(); final int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS; if (on) { winParams.flags |= bits; } else { winParams.flags &= ~bits; } win.setAttributes(winParams); } 

Hacer Theme.AppCompa t style parent

  

Y ponga getSupportActionBar().getThemedContext() en onCreate() .

 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my); getSupportActionBar().getThemedContext(); } 

Sé que esto no responde la pregunta, pero con Material Design (API 21+) podemos cambiar el color de la barra de estado agregando esta línea en la statement del tema en styles.xml :

   

Observe el android:statusBarColor , donde podemos definir el color, de lo contrario se usa el predeterminado.