web-dev-qa-db-fra.com

Barre d’état Android M Light et Dark par programmation - comment redonner de l’obscurité?

Dans Android M, nous avons la possibilité de rendre les icônes de la barre d’état sombres. Pour ce faire, nous pouvons spécifier un attribut dans le fichier XML du thème:

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

OU nous avons configuré le chat au moment de l'exécution avec ce code:

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

Et ça marche vraiment bien. Mais la question est de savoir comment définir correctement un mode de barre d'état sur sombre au moment de l'exécution.

J'ai déjà essayé ces variantes:

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

Alors, comment cela peut-il être fait de la bonne manière?

22
udenfox

La solution publiée par @Aracem est valide mais ne fonctionne pas si vous essayez de modifier également la couleur d'arrière-plan de la barre d'état. Dans mon cas, je le fais de la manière suivante.

Pour activer windowLightStatusBar (par programme, dans une classe Utils par exemple):

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

Pour restaurer l'état précédent à StatusBar:

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

La restauration de la couleur de la barre d’état suffit, elle restaure également les couleurs des icônes . TRÈS IMPORTANT: L’opération de restauration ne se produira que lorsque la vue utilisée dans setLightStatusBar (View View ..) disparaîtra (autrement dit, view.getVisibility ( ) == GONE | INVISIBLE) à l’écran. 

36

Selon le projet de Nick Butcher "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);
    }
}

Vous pouvez trouver le projet Ici

26
Aracem

J'ai assemblé cet objet utilitaire simple qui vous permet d'activer/désactiver la couleur et l'éclairage de la barre d'état pour tous les fragments. Toutefois, cela repose sur l'utilisation du composant de navigation Android Jetpack pour la navigation (Kotlin):

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

Pour utiliser cela, appelez le texte suivant à partir de la variable onViewCreated de tout fragment:

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

je vais faire quelques changements dans les réponses ci-dessus.

faire un cours

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

et appelez-le où vous voulez comme ça

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

Basé sur la réponse @ phan-van-linh, j’ai écrit ce cours pour 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
gianlucaparadise