How to Customize Status Bar in Jetpack Compose?

Jetpack Compose Customize Status Bar

Today, we will learn how to customize the system bars (status bar and navigation bar) in Jetpack Compose using the System Ui Controller library.

First, What are System Bars in Android?

By default, apps are displayed below the status bar and above the navigation bar.

The status bar displays notification and system icons at the top of the screen.

Android Status Bar

The navigation bar contains controls like back and home at the bottom of the screen.

Navigation Bar

Together, the status bar and the navigation bar are called the system bars.

Jetpack Compose System Ui Controller:

The System Ui Library is used for customizing the status bar and navigation bars.

First, add the following dependency in the app level build.gradle file:

// status bar customization
implementation "com.google.accompanist:accompanist-systemuicontroller:0.23.1"

Now, we can play with the system bars. First, we need the SystemUiController object. We can get it from the rememberSystemUiController() composable.

val systemUiController = rememberSystemUiController()

Now we can call methods to modify the system bars.

Status Bar Color:

The setStatusBarColor() method changes the status bar color.

fun setStatusBarColor(
    color: Color,
    darkIcons: Boolean = color.luminance() > 0.5f,
    transformColorForLightContent: (Color) -> Color = BlackScrimmed
)

color – The color to be applied on the status bar.

darkIcons – Whether the icons on the status bar should be dark icons.

transformColorForLightContent – It is a lambda that will be invoked to transform color if dark icons were requested but are not available.

Call the method inside the SideEffect composable. We should set the system bar colors inside the Theme block (in the onCreate() method).

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            YourProjectNameTheme {

                val systemUiController = rememberSystemUiController()
                SideEffect {
                    systemUiController.setStatusBarColor(
                        color = Color.Magenta,
                        darkIcons = false
                    )
                }

                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colors.background
                ) {
                }
            }
        }
    }
}

Output:

Status Bar Color

Instead of adding the code in every activity, you can paste it into the Theme.kt file. In the project pane, open ui > theme > Theme.kt and add the code inside the your Theme block.

Theme Jetpack Compose

In the place of BlogPostsTheme, you will see your project name (YourProjectNameTheme).

Navigation Bar Color:

Use the setNavigationBarColor() method to change the navigation bar color.

val systemUiController = rememberSystemUiController()
SideEffect {
    systemUiController.setNavigationBarColor(
        color = Color.Magenta,
        darkIcons = false
    )
}

Output:

Navigation Bar color

We can change the color of both using the setSystemBarsColor() method.

val systemUiController = rememberSystemUiController()
SideEffect {
    systemUiController.setSystemBarsColor(
        color = Color.Magenta,
        darkIcons = false
    )
}

Note: Android supports dark icons for the status bar on API 23+ and navigation bar color on API 26+. The library automatically handles the API differences and maintains the icon contrast.

How to Hide Status Bar in Jetpack Compose?

System Ui Controller provides getter and setter properties to hide or show system bars.

isNavigationBarVisible and isStatusBarVisible are for setting the visibility for the navigation bar and status bar respectively. isSystemBarsVisible is for both the system bars.

val systemUiController = rememberSystemUiController()
SideEffect {
    // navigation bar
    systemUiController.isNavigationBarVisible = false

    // status bar
    systemUiController.isStatusBarVisible = false

    // system bars
    // systemUiController.isSystemBarsVisible = false
}

How to Display Content Behind the Status Bar?

The System Ui Controller library doesn’t have methods to display content under the status bar. We need to use the old WindowManager.

Let’s make this design:

Content Behind the Status Bar

First, download the image from Unsplash and change its name to squirrel.jpg. Put it in the res > drawable folder.

We need to extend the app window to the system bars. Set the LAYOUT_NO_LIMITS flag on the window object (before the setContent block).

window.setFlags(
    WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
    WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
)

To make the image visible, set transparent color to the status bar.

val systemUiController = rememberSystemUiController()
SideEffect {
   systemUiController.setStatusBarColor(color = Color.Transparent)
}

Display the image using Image composable.

Image(
    painter = painterResource(id = R.drawable.squirrel),
    contentDescription = "Squirrel",
    contentScale = ContentScale.FillWidth,
    modifier = Modifier.fillMaxWidth()
)

Here is full the code:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // set FLAG_LAYOUT_NO_LIMITS
        // app content will extend to system bars
        // it should be before setContent block
        window.setFlags(
            WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
            WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
        )

        setContent {
            YourProjectNameTheme {

                val systemUiController = rememberSystemUiController()
                SideEffect {
                    // set transparent color so that our image is visible
                    // under the status bar
                    systemUiController.setStatusBarColor(color = Color.Transparent)
                }

                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colors.background
                ) {
                    Column(modifier = Modifier.fillMaxSize()) {
                        Image(
                            painter = painterResource(id = R.drawable.squirrel),
                            contentDescription = "Squirrel",
                            contentScale = ContentScale.FillWidth,
                            modifier = Modifier.fillMaxWidth()
                        )
                    }
                }
            }
        }
    }
}

In the above code, our app will be extended to the navigation bar also. There are 3 ways to fix this:

  1. Jetpack Compose 1.2.0 introduced insets API. Use the navigationBarsPadding() method to get the navigation bar height and apply it to the Column() layout as padding (in the above code).
  2. If you are using the earlier version, follow this guide.
  3. Set the FLAG_LAYOUT_NO_LIMITS only on the status bar.

You can find the GitHub repo of the library here. This is all about customizing the status bar in Jetpack Compose. If you have any doubts, comment below.

Continue Exploring Jetpack Compose:

Leave a Comment