web-dev-qa-db-fra.com

Barre d'état transparente - avant Android 4.4 (KitKat)

Je sais que dans Android 4.4 KitKat (API 19), il est possible de rendre la barre d'état transparente.

Mais par exemple, Go Launcher Ex et d'autres ont une option pour le rendre transparent, et cela fonctionne également sur Pre KitKat, pour moi ( Android 4. (Jelly bean)) aussi et aussi sur mon Android 4.0 ( Sandwich à la crème glacée).

Je n'avais pas besoin de root ou de privilèges spéciaux pour l'utiliser.

Téléchargez Go Launcher Ex et essayez-le vous-même. Pour moi, ce serait aussi bien si j'avais besoin de root.

Mais comment ont-ils fait ça? Comment puis-je rendre la barre d'état d'Android translucide sur les appareils pré-KitKat?

--- Pour clarifier les choses ---

Je ne parle pas de la Action Bar ; Je veux dire la barre d'état (barre de notification)!


voir ces exemples d'images:

(Remarque, cela est tiré de mon Stock Galaxy Note 3 avec Android 4.3 et Go Launcher Ex .)

(La même chose fonctionne avec mon Galaxy S2 et Android 4.0 aussi. )

Sans une barre d'état transparente:

Without transparent bar (default)

Avec barre d'état transparente activée: (je veux y parvenir sur les appareils pré 4.4 (API 19))

With transparent status bar (what I want to achieve on pre 4.4 devices in any way

26
bricklore

J'ai découvert comment obtenir une barre d'état transparente sur les appareils Samsung et Sony
exécutant au moins Android 4.0.

Pour commencer, laissez-moi vous expliquer pourquoi ce n'est pas possible sur la plupart des appareils:
Du côté officiel d'Android, il n'y a pas de solution jusqu'à KitKat (4.4).
Mais certains fabricants d'appareils comme Samsung et Sony ont ajouté cette option dans leur logiciel propriétaire.

Samsung utilise sa propre version skinnée d'Android, appelée TouchWiz, et Sony utilise également son propre système.
Ils ont leur propre implémentation de la classe View avec des drapeaux SYSTEM_UI_ Supplémentaires qui permettent d'activer une barre d'état transparente sur les appareils pré 4.4!

Mais la seule façon de prouver que ces drapeaux existent et d'y accéder est d'utiliser Reflection.
Voici ma solution:


Résoudre l'indicateur de vue:

int ResolveTransparentStatusBarFlag()
{
    String[] libs = getPackageManager().getSystemSharedLibraryNames();
    String reflect = null;

    if (libs == null)
        return 0;

    for (String lib : libs)
    {
        if (lib.equals("touchwiz"))
            reflect = "SYSTEM_UI_FLAG_TRANSPARENT_BACKGROUND";
        else if (lib.startsWith("com.sonyericsson.navigationbar"))
            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;
}

Appliquez-le sur le decorView de votre Window (à l'intérieur de n'importe quelle activité):

void ApplyTransparentStatusBar()
{
    Window window = getWindow();
    if (window != null)
    {
        View decor = window.getDecorView();
        if (decor != null)
            decor.setSystemUiVisibility(ResolveTransparentStatusBarFlag());
    }
}

Je pense qu'il y a peut-être d'autres fabricants d'appareils qui ont mis en place un tel drapeau
mais je n'ai pu comprendre ces deux-là (parce que je possède un Samsung et un appareil Sony)

20
bricklore

Utilisez ceci. :)

après super () et avant le contenu défini.

if (Build.VERSION.SDK_INT >= 19)
{
    getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}

if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 21)
{
    setWindowFlag(this, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, true);
}

if (Build.VERSION.SDK_INT >= 21)
{
    setWindowFlag(this, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, false);
    getWindow().setStatusBarColor(Color.TRANSPARENT);
}


public static void setWindowFlag(Activity activity, final int bits, boolean state)
{
    Window win = activity.getWindow();
    WindowManager.LayoutParams winParams = win.getAttributes();

    if (state)
     {
        winParams.flags |= bits;
    }
     else
     {
        winParams.flags &= ~bits;
    }
}
2
Ali Bagheri