Barra de estado y barra de acción transparentes de Android

Respuestas:

238

Estoy desarrollando una aplicación que debe verse similar en todos los dispositivos con> = API14 cuando se trata de la personalización de la barra de acción y la barra de estado. Finalmente encontré una solución y, dado que me tomó un poco de tiempo, la compartiré para guardar algunas de las suyas. Comenzamos usando una dependencia appcompat-21.

Barra de acción transparente :

valores / estilos.xml :

<style name="AppTheme" parent="Theme.AppCompat.Light">
...
</style>

<style name="AppTheme.ActionBar.Transparent" parent="AppTheme">
    <item name="android:windowContentOverlay">@null</item>
    <item name="windowActionBarOverlay">true</item>
    <item name="colorPrimary">@android:color/transparent</item>
</style>

<style name="AppTheme.ActionBar" parent="AppTheme">
    <item name="windowActionBarOverlay">false</item>
    <item name="colorPrimary">@color/default_yellow</item>
</style>


valores-v21 / styles.xml :

<style name="AppTheme" parent="Theme.AppCompat.Light">
    ...
</style>

<style name="AppTheme.ActionBar.Transparent" parent="AppTheme">
    <item name="colorPrimary">@android:color/transparent</item>
</style>

<style name="AppTheme.ActionBar" parent="AppTheme">
    <item name="colorPrimaryDark">@color/bg_colorPrimaryDark</item>
    <item name="colorPrimary">@color/default_yellow</item>
</style>

Ahora puede usar estos temas en su AndroidManifest.xmlpara especificar qué actividades tendrán un color transparente o ActionBar:

    <activity
            android:name=".MyTransparentActionbarActivity"
            android:theme="@style/AppTheme.ActionBar.Transparent"/>

    <activity
            android:name=".MyColoredActionbarActivity"
            android:theme="@style/AppTheme.ActionBar"/>

ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí

Nota: en API> = 21 para obtener la Actionbartransparencia, necesita obtener la Statusbartransparencia también; de lo contrario, no respetará sus estilos de color y permanecerá gris claro.



Barra de estado transparente (solo funciona con API> = 19) :
esta es bastante simple, solo usa el siguiente código:

protected void setStatusBarTranslucent(boolean makeTranslucent) {
        if (makeTranslucent) {
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        } else {
            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }
    }

Pero notarás un resultado funky: ingrese la descripción de la imagen aquí

Esto sucede porque cuando Statusbares transparente, el diseño utilizará su altura. Para evitar esto, solo necesitamos:

SOLUCIÓN UNO:
agregue esta línea android:fitsSystemWindows="true"en el contenedor de la vista de diseño de lo que desee colocar debajo de la barra de acción:

    ...
        <LinearLayout
                android:fitsSystemWindows="true"
                android:layout_width="match_parent"
                android:layout_height="match_parent">
            ...
        </LinearLayout>
    ...

SOLUCIÓN DOS:
Agregue algunas líneas a nuestro método anterior:

protected void setStatusBarTranslucent(boolean makeTranslucent) {
        View v = findViewById(R.id.bellow_actionbar);
        if (v != null) {
            int paddingTop = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT ? MyScreenUtils.getStatusBarHeight(this) : 0;
            TypedValue tv = new TypedValue();
            getTheme().resolveAttribute(android.support.v7.appcompat.R.attr.actionBarSize, tv, true);
            paddingTop += TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics());
            v.setPadding(0, makeTranslucent ? paddingTop : 0, 0, 0);
        }

        if (makeTranslucent) {
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        } else {
            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }
    }

¿Dónde R.id.bellow_actionbarestará el ID de vista del contenedor de diseño de lo que queramos colocar debajo de Actionbar:

...
    <LinearLayout
            android:id="@+id/bellow_actionbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
        ...
    </LinearLayout>
...

ingrese la descripción de la imagen aquí

Así que esto es todo, creo que no me estoy olvidando de algo. En este ejemplo no utilicé a, Toolbarpero creo que tendrá el mismo resultado. Así es como personalizo mi Actionbar:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        View vg = getActionBarView();
        getWindow().requestFeature(vg != null ? Window.FEATURE_ACTION_BAR : Window.FEATURE_NO_TITLE);

        super.onCreate(savedInstanceState);
        setContentView(getContentView());

        if (vg != null) {
            getSupportActionBar().setCustomView(vg, new ActionBar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
            getSupportActionBar().setDisplayShowCustomEnabled(true);
            getSupportActionBar().setDisplayShowHomeEnabled(false);
            getSupportActionBar().setDisplayShowTitleEnabled(false);
            getSupportActionBar().setDisplayUseLogoEnabled(false);
        }
        setStatusBarTranslucent(true);
    }

Nota: este es un abstract classextenso ¡ ActionBarActivity
Espero que ayude!

GuilhE
fuente
9
Realmente debería usar android: fitSystemWindows si desea asegurarse de que su Vista no esté debajo de la barra de estado transparente.
ianhanniballake
1
Eso es totalmente correcto, estaba revisando mi código y también lo estoy usando. No sé que me lo perdí en este ejemplo. ¡Lo actualizaré, gracias!
GuilhE
4
Falta MyScreenUtils.getStatusBarHeight(this) aquí la respuesta stackoverflow.com/a/3410200/1307690
Roman Nazarevych
1
¿Hay alguna manera de hacerlo translúcido y no completamente transparente? Estoy en api 23
aks
6
Para obtener los trabajos de StatusBar transparente, necesitaba agregar FLAG_LAYOUT_NO_LIMITS Flag, poniendo el código getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);después de esogetWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
Eduardo ER
3

Soporta después de KITKAT. Simplemente agregue el siguiente código dentro del método onCreate de su actividad. No es necesario realizar modificaciones en el archivo de manifiesto.

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                Window w = getWindow(); // in Activity's onCreate() for instance
                w.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
            }
Indika Ruwan Senavirathne
fuente
9
Esto hace que la barra de navegación también sea transparente
NOlivNeto
0

Simplemente agregue estas líneas de código a su archivo java de actividad / fragmento:

getWindow().setFlags(
    WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
    WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
);
Faisal Shaikh
fuente