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