Android M Light and Dark status bar programmatically - how to make it dark again?

前端 未结 10 1640
自闭症患者
自闭症患者 2020-12-24 10:49

In the Android M we have ability to make status bar icons dark. To do that we can specify attribute in the theme\'s xml:



        
相关标签:
10条回答
  • 2020-12-24 11:38

    I base on @Aracem and @Carlos Hernández Gil but I think it will easy to understand if we use bitwise XOR (^ 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
        }
    }
    

    Explain

    First, look at SYSTEM_UI_FLAG_LIGHT_STATUS_BAR and setSystemUiVisibility

    /**
     * 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;
            ...
        }
    }
    

    I think 2 lines code below is quite hard to understand

    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
    

    At first look, I just think we can use simple like

    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)
    

    But we should use | and ^ because
    Example, we want to set both status bar and navigationbar to light, then we will use

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

    When we don't want status bar is light anymore, we can use

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

    To know more why we use | and ^, I think the tutorial below may help https://medium.com/@JakobUlbrich/flag-attributes-in-android-how-to-use-them-ac4ec8aee7d1 Here is my understand. Hope this help

    0 讨论(0)
  • 2020-12-24 11:38

    To change to light status bar use:-

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 
         activity?.window?.decorView?.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
    
    

    To change back to dark status bar :-

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 
         activity?.window?.decorView?.systemUiVisibility = 0
    
    0 讨论(0)
  • 2020-12-24 11:41

    According to Nick Butcher's project "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);
        }
    }
    

    You can find this file here.

    0 讨论(0)
  • 2020-12-24 11:44

    I put together this simple utility object that allows you to change status bar color and light status bar on/off for within any fragment. However, this relies on using the Android Jetpack Navigation component for 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
                    }
                }
            }
        }
    }
    

    To use this, call the following from within any fragment's onViewCreated:

    StatusBarUtil.changeStatusBarColor(requireActivity(), someDarkColor, false)
    
    0 讨论(0)
提交回复
热议问题