Common system bar requirements

For the system bar (status bar and navigation bar), the following requirements are common

  1. Set the system bar color
  2. Implement fully transparent/semi-transparent system bar – make the system bar overlay the application content
  3. Ensure readability of icon text on system bar
    • Light mode, black text on white background
    • Dark mode, white text on black background
  4. Immersive – Hides the system bar, but can be redisplayed through interaction. There are three interaction modes:
    • Touch screen display
    • Slide across the edge of the screen
    • Slide across the edge of the screen and hide again after a few seconds

Set the system bar color

  • API21 + available
  • WindowManager. LayoutParams. FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS must be set, the default is already set the tag specified by the application of window bar area is responsible for drawing system background, At the same time, the background of the system bar window is set to fully transparent. If this flag is not set, the background of the system bar window is set to black
// Set the status bar color
window.statusBarColor = color

// Set the navigation bar color
window.navigationBarColor = color

// API28+ can set the navigation bar separator color
window.navigationBarDividerColor = color
Copy the code

Fully transparent/semi-transparent system bar

Make the system bar cover the application content, and then set the color of the system bar to achieve a fully transparent/translucent system bar

  • API16 + available
window.decorView.apply {
    // Set the status bar system bar overlays the application content
    systemUiVisibility = systemUiVisibility or View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 
    
    // Set the navigation bar system bar to overlay the application content
    systemUiVisibility = systemUiVisibility or View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 
} 
Copy the code

Note: Setting SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN only works on the status bar, but setting SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION works on both the status bar and navigation bar

  • API30+ provides a new API,View.SYSTEM_UI_FLAG_LAYOUT_*Marked as abandoned
// When set to true, the framework will still use the old API
// When set to false, the status bar and navigation bar overwrite the application content and cannot be set separately
void setDecorFitsSystemWindows(boolean decorFitsSystemWindows)
Copy the code

API19+ can also implement a fully transparent system bar using the following flags, but API30+ has been deprecated and is not recommended

  • WindowManager. LayoutParams. FLAG_TRANSLUCENT_STATUS system automatically added after settingView.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
  • WindowManager. LayoutParams. FLAG_TRANSLUCENT_NAVIGATION system automatically added after settingView.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION

Ensure readability of icon text on system bar

When the transparent system bar is set, the system bar is overlaid on the application content. If the icon text on the system bar is not contrasted enough with the application content, the system bar icon text will not be visible

In API23+, you can set the status bar light mode. In API26+, you can set the navigation bar light mode

window.decorView.systemUiVisibility = window.decorView.systemUiVisibility or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
window.decorView.systemUiVisibility = window.decorView.systemUiVisibility or View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
Copy the code

In API29+, when the system bar color is 0(transparent), you can set whether to draw a translucent background by the system bar window to provide contrast

  • When the system bar is in light mode, draw a white translucent background with black icon text
  • When the system bar is in dark mode, draw a black translucent background with white icon text
// The status bar defaults to false
window.isStatusBarContrastEnforced = false
// Navigation bar defaults to true
window.isNavigationBarContrastEnforced = true
Copy the code

System bar general operation

To summarize, you can see that the system bar has the following basic operations, which can be used in combination

  • Set the system bar background color
  • Settings override application content
  • Set the system bar to a light color mode
  • Sets whether to display the default translucent background of the system bar when the color of the system spin bar is 0

Define the following interfaces to easily modify the system bar status

interface Bar { 
    // Set the background color of the system bar
    fun color(@ColorInt color: Int): Bar

    // Set overlays on the application content
    fun overlay(value: Boolean = true): Bar
    
    // Set the system bar to a light-colored mode
    fun light(value: Boolean = true): Bar

    // Sets whether to display the default translucent background of the system bar when the color of the system spinning bar is 0
    fun contrast(value: Boolean = true): Bar
}


Copy the code

Provide extension functions

fun Activity.systemBars(a): Bar = SystemBars(window)
fun Fragment.systemBars(a): Bar = SystemBars(requireActivity().window)
fun Dialog.systemBars(a): Bar = SystemBars(window!!)

fun Activity.statusBar(a): Bar = StatusBar(window)
fun Fragment.statusBar(a): Bar = StatusBar(requireActivity().window)
fun Dialog.statusBar(a): Bar = StatusBar(window!!)

fun Activity.navigationBar(a): Bar = NavigationBar(window)
fun Fragment.navigationBar(a): Bar = NavigationBar(requireActivity().window)
fun Dialog.navigationBar(a): Bar = NavigationBar(window!!)

var Window.isDrawsSystemBarBackgrounds: Boolean

var Window.isStatusBarOverlay: Boolean
var Window.isStatusBarLight: Boolean

var Window.isNavigationBarOverlay: Boolean 
var Window.isNavigationBarLight: Boolean
Copy the code

use

// Set the transparent system bar
statusBar().overlay().color(Color.TRANSPARENT)

// Set the translucent system bar
statusBar().overlay().color(0x66ff0000) 
Copy the code

Manipulating color/light/contrast does not work in immersive mode

immersion

Android offers three immersion modes, all of which hide the system bar

  • Tilt back mode – Touch the screen to redisplay the system bar
  • Immersion mode – Slide across the edge of the screen to redisplay the system bar
  • Sticky immersion mode – Redisplay the system bar by sliding across the edge of the screen and hide it after a few seconds. This mode cannot receive the visibility change event of the system bar

fun Window.immersive(enable: Boolean = true, swipe: Boolean = false, transientBars: Boolean = false) {
    // Do not want the layout to change when the system bar is hidden/displayed
    WindowCompat.setDecorFitsSystemWindows(this, !enable)

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        if (enable) {
            // How to redisplayinsetsController? .systemBarsBehavior =when {
                swipe && transientBars -> WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
                swipe -> WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_SWIPE
                else -> WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_TOUCH
            }
            // Hide system barinsetsController? .hide(WindowInsets.Type.systemBars()) }else {
            // Exit immersioninsetsController? .show(WindowInsets.Type.systemBars()) } }else {
        // Hide system bar
        val flags = View.SYSTEM_UI_FLAG_FULLSCREEN or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION

        val immersiveFlags = when {
            // Exit immersion! enable -> View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or View.SYSTEM_UI_FLAG_IMMERSIVE// How to redisplay
            swipe && transientBars -> View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
            swipe -> View.SYSTEM_UI_FLAG_IMMERSIVE
            else -> 0
        }
        setSystemUiVisibility(flags or immersiveFlags, enable)
    }
}
Copy the code

Tool library

Github.com/czy1121/sys…

DEMO APK download: github.com/czy1121/sys…

repositories { maven { url "https://gitee.com/ezy/repo/raw/android_public/"} } dependencies { implementation "Me. Reezy. Jetpack: systembars: 0.4.0"}Copy the code