it-swarm.com.de

Android M Light und Dark Statusleiste programmgesteuert - wie kann man sie wieder dunkel machen?

Im Android M haben wir die Möglichkeit, Statusleisten-Icons dunkel zu machen. Dazu können wir Attribute in der XML des Themes angeben:

<item name="Android:windowLightStatusBar">true</item>

ODER wir setzen es zur Laufzeit mit diesem Code ein:

View someView = findViewById(R.id.some_view);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    someView.setSystemUiVisibility(someView.getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}

Und es funktioniert eigentlich gut. Aber die Frage ist, wie man einen Statusleistenmodus zur Laufzeit richtig auf "dunkel" setzen kann.

Ich habe diese Varianten bereits ausprobiert:

// Makes status bar mode dark, but also hides it along with all navigation views. 
someView.setSystemUiVisibility(someView.getSystemUiVisibility() | ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);

// Does nothing 
someView.setSystemUiVisibility(someView.getSystemUiVisibility() & ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);

// Also does nothing 
someView.setSystemUiVisibility(someView.getSystemUiVisibility() ^ View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);

Wie kann es also richtig gemacht werden?

22
udenfox

Die von @Aracem veröffentlichte Lösung ist gültig, funktioniert jedoch nicht, wenn Sie versuchen, auch die Hintergrundfarbe der Statusleiste zu ändern. In meinem Fall mache ich das folgendermaßen.

So aktivieren Sie windowLightStatusBar (programmgesteuert innerhalb einer Utils-Klasse):

 public static void setLightStatusBar(View view,Activity activity){


            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

                int flags = view.getSystemUiVisibility();
                flags |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
                view.setSystemUiVisibility(flags);
                activity.getWindow().setStatusBarColor(Color.WHITE); 
            }
}

So stellen Sie den vorherigen Status in StatusBar wieder her:

  public static void clearLightStatusBar(Activity activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            Window window = activity.getWindow();
            window.setStatusBarColor(ContextCompat
                 .getColor(activity,R.color.colorPrimaryDark)); 
        }
    }

Das Wiederherstellen der Farbe der Statusleiste reicht aus, es werden auch die Farben der Symbole wiederhergestellt. VORSICHT: Der Wiederherstellungsvorgang wird erst ausgeführt, wenn die in setLightStatusBar (View view ..) verwendete Ansicht verschwindet (dh view.getVisibility ( ) == GONE | INVISIBLE) vom Bildschirm aus. 

36

Laut Nick Butcher's Projekt "Plaid" 

public static void clearLightStatusBar(@NonNull View view) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        int flags = view.getSystemUiVisibility();
        flags &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
        view.setSystemUiVisibility(flags);
    }
}

Sie finden das Projekt Hier

26
Aracem

Ich stütze mich auf @Aracem und @Carlos Hernández Gil, aber ich denke, es wird leicht zu verstehen sein, wenn wir bitweises XOR ( verwenden ) ^ Operator in Java)

private void setLightStatusBar(Activity activity) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        int flags = activity.getWindow().getDecorView().getSystemUiVisibility(); // get current flag
        flags |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;   // add LIGHT_STATUS_BAR to flag
        activity.getWindow().getDecorView().setSystemUiVisibility(flags); 
        activity.getWindow().setStatusBarColor(Color.GRAY); // optional
    }
}

private void clearLightStatusBar(Activity activity) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        int flags = activity.getWindow().getDecorView().getSystemUiVisibility(); // get current flag
        flags = flags ^ View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; // use XOR here for remove LIGHT_STATUS_BAR from flags
        activity.getWindow().getDecorView().setSystemUiVisibility(flags);
        activity.getWindow().setStatusBarColor(Color.GREEN); // optional
    }
}

Erklären Sie

Schauen Sie sich zuerst SYSTEM_UI_FLAG_LIGHT_STATUS_BAR Und setSystemUiVisibility an.

/**
 * Flag for {@link #setSystemUiVisibility(int)}: Requests the status bar to draw in a mode that
 * is compatible with light status bar backgrounds.
 */
public static final int SYSTEM_UI_FLAG_LIGHT_STATUS_BAR = 0x00002000;

public void setSystemUiVisibility(int visibility) {
    if (visibility != mSystemUiVisibility) {
        mSystemUiVisibility = visibility;
        ...
    }
}

Ich denke, 2 Zeilen Code unten ist ziemlich schwer zu verstehen

flags |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; // for set light status bar
flags = flags ^ View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; // for clear light status bar

Auf den ersten Blick denke ich nur, dass wir einfach wie verwenden können

flags = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; // for set light status bar
flags = 0; // for clear light status bar (0 <=> LIGHT_STATUS_BAR <=> default systemUiVisibility)

Aber wir sollten | Und ^ Verwenden, weil
Als Beispiel möchten wir sowohl die Statusleiste als auch die Navigationsleiste auf hell setzen, dann werden wir verwenden

flags = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR | View.View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
activity.getWindow().getDecorView().setSystemUiVisibility(flags);

Wenn die Statusleiste nicht mehr leuchtet, können wir sie verwenden

flags = View.View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
activity.getWindow().getDecorView().setSystemUiVisibility(flags);

OR

flags = activity.getWindow().getDecorView().getSystemUiVisibility();
flags = flags ^ View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; 
activity.getWindow().getDecorView().setSystemUiVisibility(flags);

Um mehr darüber zu erfahren, warum wir | Und ^ Verwenden, kann das folgende Tutorial hilfreich sein https://medium.com/@JakobUlbrich/flag-attributes-in-Android- how-to-use-them-ac4ec8aee7d1 Hier ist mein Verständnis. Ich hoffe das hilft

12
Phan Van Linh

Ich habe dieses einfache Hilfsobjekt zusammengestellt, mit dem Sie die Farbe der Statusleiste und die Statusleiste der Leuchte für jedes Fragment ein/ausschalten können. Dies setzt jedoch die Verwendung der Android Jetpack-Navigationskomponente für die Navigation (Kotlin) voraus:

object StatusBarUtil {
    fun changeStatusBarColor(activity: Activity, @ColorInt color: Int, lightStatusBar: Boolean) {
        activity.window?.let { win ->
            val nav = Navigation.findNavController(activity, R.id.your_nav_Host_fragmen /* TODO: Use the ID of your nav Host fragment */)
            val currentDest = nav.currentDestination?.id
            val oldColor = win.statusBarColor
            val oldFlags = win.decorView.systemUiVisibility
            win.statusBarColor = color

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                var flags = oldFlags
                flags = if (lightStatusBar) {
                    flags or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
                } else {
                    flags and View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.inv()
                }
                win.decorView.systemUiVisibility = flags
            }

            nav.addOnNavigatedListener { _, dest ->
                if (dest.id != currentDest) {
                    win.statusBarColor = oldColor
                    win.decorView.systemUiVisibility = oldFlags
                }
            }
        }
    }
}

Um dies zu verwenden, rufen Sie in onViewCreated eines beliebigen Fragments Folgendes auf:

StatusBarUtil.changeStatusBarColor(requireActivity(), someDarkColor, false)
3
hsson

ich werde einige Änderungen in den obigen Antworten vornehmen.

mach eine Klasse

 public class DarkStatusBar {
    public static void setLightStatusBar(View view, Activity activity){

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

            int flags = view.getSystemUiVisibility();
            flags |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
            view.setSystemUiVisibility(flags);
            activity.getWindow().setStatusBarColor(Color.WHITE);
        }
    }
}

und nenne es wo immer du willst

        Window window = getWindow();
        View view = window.getDecorView();
        DarkStatusBar.setLightStatusBar(view,this);
1
roshan posakya

Basierend auf der @ phan-van-linh-Antwort schrieb ich diese Klasse für Xamarin Android

public static class ActivityExtensions
{
    public static void SetLightStatusBar(this Activity activity)
    {
        int flags = (int)activity.Window.DecorView.SystemUiVisibility; // get current flag
        flags |= (int)SystemUiFlags.LightStatusBar;   // add LIGHT_STATUS_BAR to flag
        activity.Window.DecorView.SystemUiVisibility = (StatusBarVisibility)flags;
        //activity.Window.SetStatusBarColor(Color.GRAY); // optional
    }

    public static void ClearLightStatusBar(this Activity activity)
    {
        int flags = (int)activity.Window.DecorView.SystemUiVisibility; // get current flag
        flags = flags ^ (int)SystemUiFlags.LightStatusBar; // use XOR here for remove LIGHT_STATUS_BAR from flags
        activity.Window.DecorView.SystemUiVisibility = (StatusBarVisibility)flags;
        //activity.Window.setStatusBarColor(Color.GREEN); // optional
    }
}
0