3

My issue is like the pic Wrong color

I set up status bar color like this:

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

My top bar

@Composable
fun ProminentTopAppBarWithImage() {
    TopAppBar(
        modifier = Modifier.height(200.dp),
        contentPadding = PaddingValues(all = 0.dp) // (1)
    ) {
        Box(modifier = Modifier.fillMaxSize().background(SaveDoneBackGroundGradient)) { // (2)
            Row( // (4)
                modifier = Modifier
                    .fillMaxSize()
                    .padding(horizontal = 4.dp) // (5)
            ) {
                /*...*/
            }
        }
    }
}

Any solutions for this issue?

z.g.y
  • 5,512
  • 4
  • 10
  • 36
bovietvidai
  • 105
  • 5
  • I swear i have the exact thing implemented in my project rn. I'm just too lazy to open my laptop and post it here, but I'll get over it in a day or two. I'll try, don't lose hope my friend. Also if you're lucky, Dr. Thrace will spawn out of thin air to answer your question with tremendous unbelievable detail. – Richard Onslow Roper Jan 09 '23 at 18:27
  • 1
    @RichardOnslowRoper are you the movie critic? – BraveEvidence Jul 23 '23 at 12:02
  • @BraveEvidence ? Even tho Dr. Thrace didn't spawn up, Holy Gabriele Mariotti did appear to help (He's mythic). – Richard Onslow Roper Jul 25 '23 at 07:06

3 Answers3

4

You can do something different.

// Turn off the decor fitting system windows
WindowCompat.setDecorFitsSystemWindows(window, false)

setContent {
    //...
}

Them apply to the status bar a Transparent color:

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

Then apply the gradient to TopAppBar content:

TopAppBar(
    modifier = Modifier.height(200.dp),
    contentPadding = PaddingValues(all = 0.dp) 
) {
    Box(Modifier.fillMaxSize().background(gradientGreenRed))
}

enter image description here

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
2

I think the only way for a status bar to have and match a gradient color of the content is to resort back to old window/drawable config.

Taken the idea from this post, you'll have to create an xml drawable that will match the colors and orientation of your gradient background you use in your composable container/layout.

res/drawable/gradient_horizontal.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <gradient
        android:type="linear"
        android:angle="0"
        android:startColor="#9881de"
        android:endColor="#6b50ba"  />
</shape>

and have this window configuration, where you will set the drawable as the window background

fun gradientStatusBar(activity: Activity) {
    val window: Window = activity.window
    val background = ContextCompat.getDrawable(activity, R.drawable.gradient_horizontal)
    window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)

    window.statusBarColor = ContextCompat.getColor(activity,android.R.color.transparent)
    window.navigationBarColor = ContextCompat.getColor(activity,android.R.color.transparent)
    window.setBackgroundDrawable(background)
}

and then call it in your activity

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        gradientStatusBar(this) // call it here
        setContent {
            Box(
                modifier = Modifier
                    .fillMaxSize()
                    .background(
                        brush = Brush.horizontalGradient(
                            colors = listOf(
                                Color(0xFF9881de),
                                Color(0xFF6b50ba)
                            )
                        )
                    )
            )
...

You'll get something like this

enter image description here

You'll just have to adjust both the drawable and your background gradient colors/orientation if you want to change everything and maintain a uniform look of your status bar and the content.

z.g.y
  • 5,512
  • 4
  • 10
  • 36
-2

So listen, the idea of just having a single screen have a gradient background is not supported in any version of Android, out-of-the-box. Still, in Compose it it often the case that Composables represent entire screens, which begs a standard architecture to be designed. Now, in those screen-representing composable, you could reserve a spot, like on the first line, for example to set the status bar color. If you want maximum control, just set the status bar color of every screen manually. This way you do get full customization, along with the benefits of keeping clean, predictable code. Accompanist shall provide u with the most convenient APIs to do this. As far as the gradient background is concerned, it could be achieved with this:

private fun setStatusBarGradient(vararg colors: Int) {
        val gd = GradientDrawable(
            GradientDrawable.Orientation.LEFT_RIGHT, // change per needs
            colors
        )
//        gd.cornerRadius = 0f // change per needs

        val window: Window = this.window
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)

        window.statusBarColor = ContextCompat.getColor(this, android.R.color.transparent)
        window.navigationBarColor =
            ContextCompat.getColor(this, android.R.color.transparent)
        window.setBackgroundDrawable(gd)
    }

I might have taken this from stack, but that was very long ago. Credits to the appropriate owner, although it was definitely not on Compose and was probably in Java. Still, just mentioning.

Richard Onslow Roper
  • 5,477
  • 2
  • 11
  • 42