Barre d'état et barre d'action transparentes Android

97

Je l' ai fait quelques recherches sur ce sujet et je ne pouvais pas trouver une solution complète donc, étape par étape et avec quelques essais et erreurs, je trouve enfin comment pouvons - nous obtenir ces résultats: ayant un transparent ou coloré Actionbaret Statusbar. Voir ma réponse ci-dessous.

GuilhE
la source

Réponses:

238

Je développe une application qui doit ressembler à tous les appareils avec> = API14 en ce qui concerne la personnalisation de la barre d'action et de la barre d'état. J'ai enfin trouvé une solution et comme cela a pris un peu de temps, je la partagerai pour en sauver une partie. Nous commençons par utiliser une dépendance appcompat-21.

Barre d'action transparente :

values ​​/ styles.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>


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

Vous pouvez maintenant utiliser ces thèmes dans votre AndroidManifest.xmlpour spécifier quelles activités auront un transparent ou une couleur ActionBar:

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

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

entrez la description de l'image ici entrez la description de l'image ici entrez la description de l'image ici entrez la description de l'image ici entrez la description de l'image ici

Remarque: dans API> = 21 pour obtenir le Actionbartransparent, vous devez également obtenir le Statusbartransparent, sinon ne respectera pas vos styles de couleur et restera gris clair.



Transparent Statusbar (ne fonctionne qu'avec API> = 19) :
Celui-ci est assez simple, utilisez simplement le code suivant:

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

Mais vous remarquerez un résultat génial: entrez la description de l'image ici

Cela se produit car lorsque le Statusbarest transparent, la mise en page utilise sa hauteur. Pour éviter cela, nous devons simplement:

SOLUTION ONE:
Ajoutez cette ligne android:fitsSystemWindows="true"dans votre conteneur de vue de mise en page de ce que vous voulez placer sous la barre d'action:

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

SOLUTION DEUX:
Ajoutez quelques lignes à notre méthode précédente:

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

R.id.bellow_actionbarsera l'ID de vue du conteneur de mise en page de tout ce que nous voulons être placé sous le Actionbar:

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

entrez la description de l'image ici

Alors ça y est, ça pense que je n'oublie pas quelque chose. Dans cet exemple, je n'ai pas utilisé de Toolbarmais je pense que cela aura le même résultat. Voici comment je personnalise mon 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);
    }

Remarque: c'est un abstract classqui prolonge l' ActionBarActivity
espoir que cela aide!

GuilhE
la source
9
Vous devriez vraiment utiliser android: fitsSystemWindows si vous voulez vous assurer que votre vue ne se trouve pas sous la barre d'état transparente.
ianhanniballake
1
C'est tout à fait correct, j'étais en train de revoir mon code et je l'utilise aussi. Je ne sais pas que je l'ai manqué dans cet exemple. Je vais le mettre à jour, merci!
GuilhE
4
Vous MyScreenUtils.getStatusBarHeight(this)
manquez
1
existe-t-il un moyen de le rendre translucide et non complètement transparent? Je suis sur l'API 23
aks le
6
Pour obtenir Transparent StatusBar Works, j'avais besoin d'ajouter FLAG_LAYOUT_NO_LIMITS Flag, en mettant le code getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);après celagetWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
Eduardo ER
3

Il prend en charge après KITKAT. Ajoutez simplement le code suivant dans la méthode onCreate de votre activité. Pas besoin de modifications au fichier Manifest.

 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
la source
9
Cela rend la barre de navigation également transparente
NOlivNeto
0

Ajoutez simplement ces lignes de code à votre fichier java activité / fragment:

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