androidkotlinandroid-jetpack-composeandroid-statusbarjetpack-compose-accompanist

Drawing content over safearea in material3 with jetpack compose does not work


I am using the latest BOM version of jetpack compose: implementation platform('androidx.compose:compose-bom:2023.06.01') align with materail3. I need my content to ignore safe area. I have already tried the solution of using accompanist library for this

In MainActivity.kt I added

WindowCompat.setDecorFitsSystemWindows(window, false)

Inside my composable I added

val systemUiController = rememberSystemUiController()
    val useDarkIcons = !isSystemInDarkTheme()

    DisposableEffect(systemUiController, useDarkIcons) {
        // Update all of the system bar colors to be transparent, and use
        // dark icons if we're in light theme
        systemUiController.setSystemBarsColor(
            color = Color.Transparent,
            darkIcons = useDarkIcons
        )

        // setStatusBarColor() and setNavigationBarColor() also exist

        onDispose {}
    }

I also tried adding

 Scaffold(
        content = {
            Box(
                modifier = Modifier.padding(it.calculateTopPadding())
            ) {....

But still my content does not ignore safe area. In short I just need to hide the default status bar so my image can occupy entire height


Solution

  • As I got it correctly you wanted to achieve the following behavior :

    enter image description here

    If so, there 4 steps to achieve this.

    It seems you didn't play around with WindowInsets =) (see point #3)

    #1 In Activity before setContent{} add

     WindowCompat.setDecorFitsSystemWindows(window, false)
    
      override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
    
            WindowCompat.setDecorFitsSystemWindows(window, false)
            setContent {
                val darkModeState by darkModeState.collectAsStateWithLifecycle()
    
                AppTheme(darkTheme = darkModeState) {
                    MainApp()
                }
            }
        }
    

    #2 In the app theme set the status bar as transparent

      window.statusBarColor = Color.Transparent.toArgb()
    
    @Composable
    fun AppTheme(
        darkTheme: Boolean = true,
        content: @Composable () -> Unit
    ) {
        val colorScheme = when {
            darkTheme -> DarkColorScheme
            else -> LightColorScheme
        }
        val view = LocalView.current
        if (!view.isInEditMode) {
            SideEffect {
                val window = (view.context as Activity).window
                window.statusBarColor = Color.Transparent.toArgb()
                window.navigationBarColor = Color.Transparent.toArgb()
                WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = !darkTheme
                WindowCompat.getInsetsController(window, view).isAppearanceLightNavigationBars = !darkTheme
    
            }
        }
    
        MaterialTheme(
            colorScheme = colorScheme,
            typography = Typography
        ) {
            Box(
                modifier = Modifier
                    .fillMaxSize()
                    .background(color = MaterialTheme.colorScheme.background)
            ) {
                content()
            }
        }
    }
    

    #3 In Scaffold() set insets to 0 (you can play around with it if you don't need 0 for all sides)

    contentWindowInsets = WindowInsets(0.dp, 0.dp, 0.dp, 0.dp)
    
    @Composable
    fun HomeScreen(
        nestedNavGraph: @Composable () -> Unit,
        bottomBar: @Composable () -> Unit
    ) {
    
        Scaffold(bottomBar = bottomBar,
            contentWindowInsets = WindowInsets(0.dp, 0.dp, 0.dp, 0.dp)
        ) { paddingValues ->
            ScreenBackground(
                modifier = Modifier
                    .fillMaxSize()
                    .padding(paddingValues)
            ) {
                nestedNavGraph.invoke()
            }
        }
    }
    

    #4 Don't forget to remove Modifier.safeContentPadding() or .safeDrawingPadding() everywhere if there is.

    Hoping it would help.