web-dev-qa-db-fra.com

Android barre d'état et barre d'actions transparentes

J'ai fait quelques recherches sur ce sujet et je ne trouvais pas de solution complète. Alors, pas à pas et après quelques essais, je découvre enfin comment atteindre ces résultats: avoir un résultat transparent ou coloré Actionbar et Statusbar. Voir ma réponse ci-dessous.

91
GuilhE

Je développe une application qui doit ressembler à tous les appareils avec> = API14 en matière de personnalisation de la barre d'action et de la barre d'état. J'ai enfin trouvé une solution et comme cela m'a pris un peu de temps, je vais la partager pour sauver une partie de votre vie. 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.xml pour spécifier les activités qui auront un ActionBar transparent ou coloré:

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

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

enter image description hereenter image description hereenter image description hereenter image description hereenter image description here

Remarque: dans API> = 21 pour obtenir le Actionbar transparent, vous devez également obtenir le Statusbar transparent, sinon vous ne respecterez pas vos styles de couleur et resterez gris clair.



Barre d'état transparente (ne fonctionne qu'avec des 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 funky: enter image description here

Cela se produit car lorsque la variable Statusbar est transparente, la disposition utilise sa hauteur. Pour éviter cela, nous devons simplement:

SOLUTION UNE:
Ajoutez cette ligne Android:fitsSystemWindows="true" dans le conteneur de la vue de présentation de tout 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_actionbar sera l'identifiant de la vue du conteneur d'agencement de tout ce que nous voulons placer sous la variable Actionbar:

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

enter image description here

Alors ça y est, je pense que je n'oublie rien. Dans cet exemple, je n'ai pas utilisé de Toolbar mais je pense que le résultat sera le même. Voici comment je personnalise ma 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: ceci est un abstract class qui étend ActionBarActivity
J'espère que ça aide!

231
GuilhE

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

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