Lollipop: dibuja detrás de la barra de estado con su color establecido en transparente
He configurado el color de mi barra de estado en transparente para Lollipop solo con la siguiente línea en mi tema:
<item name="android:statusBarColor">@android:color/transparent</item>
Ahora necesito dibujar detrás de él, pero no puedo dibujar ninguna vista detrás de él. Sé cómo hacerlo con la windowTranslucentStatus
propiedad, pero no quiero usar esta propiedad ya que ignorará el color de la barra de estado establecida en transparente.
Método 1:
Para lograr una barra de estado completamente transparente, debe usar statusBarColor
, que solo está disponible en API 21 y superior. windowTranslucentStatus
está disponible en API 19 y superior, pero agrega un fondo teñido para la barra de estado. Sin embargo, la configuración windowTranslucentStatus
logra una cosa que cambiar statusBarColor
a transparente no logra: establece las banderas SYSTEM_UI_FLAG_LAYOUT_STABLE
y . SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
La forma más sencilla de obtener el mismo efecto es configurar manualmente estas banderas, lo que efectivamente desactiva las inserciones impuestas por el sistema de diseño de Android y te deja a tu suerte.
Llamas a esta línea en tu onCreate
método:
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
Asegúrese de configurar también la transparencia en /res/values-v21/styles.xml:
<item name="android:statusBarColor">@android:color/transparent</item>
O establezca la transparencia mediante programación:
getWindow().setStatusBarColor(Color.TRANSPARENT);
El lado bueno de este enfoque es que los mismos diseños también se pueden usar en API 19 cambiando la barra de estado transparente por la barra de estado translúcida teñida.
<item name="android:windowTranslucentStatus">true</item>
Método #2:
Si solo necesita pintar una imagen de fondo debajo de su barra de estado, en lugar de colocar una vista detrás de ella, esto se puede hacer simplemente configurando el fondo del tema de su actividad en la imagen deseada y configurando la transparencia de la barra de estado como se muestra en el método # 1. Este fue el método que utilicé para crear las capturas de pantalla para el artículo de Android Police de hace unos meses.
Método #3:
Si tiene que ignorar las inserciones estándar del sistema para algunos diseños y mantenerlas funcionando en otros, la única forma viable de hacerlo es trabajar con la ScrimInsetsFrameLayout
clase frecuentemente vinculada. Por supuesto, algunas de las cosas que se hacen en esa clase no son necesarias para todos los escenarios. Por ejemplo, si no planea utilizar la superposición de la barra de estado sintética, simplemente comente todo el contenido del init()
método y no se moleste en agregar nada al archivo attrs.xml. He visto que este enfoque funciona, pero creo que encontrará otras implicaciones que pueden requerir mucho trabajo.
También vi que te opones a incluir múltiples diseños. En el caso de envolver un diseño dentro de otro, donde ambos tienen match_parent
altura y ancho, las implicaciones en el rendimiento son demasiado triviales como para preocuparse. De todos modos, puedes evitar esa situación por completo cambiando la clase desde la que se extiende FrameLayout
a cualquier otro tipo de clase de Diseño que desees. Funcionará bien.
Esto funcionó para mi caso.
// Create/Set toolbar as actionbar
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Check if the version of Android is Lollipop or higher
if (Build.VERSION.SDK_INT >= 21) {
// Set the status bar to dark-semi-transparentish
getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
// Set paddingTop of toolbar to height of status bar.
// Fixes statusbar covers toolbar issue
toolbar.setPadding(0, getStatusBarHeight(), 0, 0);
}
// A method to find height of the status bar
public int getStatusBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
Para obtener más información sobre cómo trabajar con barras de estado: youtube.com/watch?v=_mGDMVRO3iE
Prueba este tema
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="colorPrimaryDark">@android:color/transparent</item>
<item name="colorPrimary">@color/md_blue_200</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
</style>
Asegúrese de que su conjunto de diseño
android:fitsSystemWindows="false"
La solución de Cody Toombs casi me funcionó. No estoy seguro de si esto está relacionado con Xamarin o no, pero ahora tengo una solución aceptable:
Esta es mi configuración:
Tengo un proyecto de Android en el que hice referencia a los paquetes Android.Support v4 y v7. Tengo dos estilos definidos:
valores/estilos.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<resources>
<style name="MyStyle" parent="@style/Theme.AppCompat.Light.NoActionBar">
<item name="android:windowTranslucentStatus">true</item>
</style>
</resources>
valores-v21/styles.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<resources>
<style name="MyStyle" parent="@style/Theme.AppCompat.Light.NoActionBar">
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
</resources>
AndroidManifest apunta a "MyStyle":
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.agn.test.test">
<uses-sdk android:minSdkVersion="10" />
<application android:allowBackup="true" android:icon="@mipmap/icon" android:label="@string/app_name" android:theme="@style/MyStyle">
</application>
</manifest>
Y finalmente el código en la Actividad Principal:
[Activity (Label = "Test", MainLauncher = true, Icon = "@mipmap/icon")]
public class MainActivity : Activity
{
protected override void OnCreate (Bundle savedInstanceState)
{
base.OnCreate (savedInstanceState);
SetContentView (Resource.Layout.Main);
//Resource.Layout.Main is just a regular layout, no additional flags. Make sure there is something in there like an imageView, so that you can see the overlay.
var uiOptions = (int)Window.DecorView.SystemUiVisibility;
uiOptions ^= (int)SystemUiFlags.LayoutStable;
uiOptions ^= (int)SystemUiFlags.LayoutFullscreen;
Window.DecorView.SystemUiVisibility = (StatusBarVisibility)uiOptions;
Window.AddFlags (WindowManagerFlags.DrawsSystemBarBackgrounds);
}
}
Observe que configuré el indicador DrawsSystemBarBackgrounds, esto marca la diferencia
Window.AddFlags (WindowManagerFlags.DrawsSystemBarBackgrounds);
Pasé mucho tiempo haciéndolo bien; de hecho, demasiado tiempo. Esperemos que esta respuesta ayude a cualquiera que intente lograr lo mismo.