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?
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
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.
I don't think SystemUiController
allows setting a gradient as status bar color. What you can do instead is draw behind status bar for that particular screen so that the gradient that you use for TopAppBar will be shown behind the status bar also.
@Composable
fun YourScreen() {
val window = (LocalContext.current as Activity).window
DisposableEffect(Unit) {
WindowCompat.setDecorFitsSystemWindows(window, false)
onDispose {
WindowCompat.setDecorFitsSystemWindows(window, true)
}
}
YourTopAppBar()
}
Note: LocalContext.current as Activity
will work if the current context is an Activity
if you have this screen inside a Fragment
, this case will fail and you will have to get the activity context from current context. If that's the case, you can use the following extension function to get Activity
from current Context
:
fun Context.getActivity(): Activity? = when (this) {
is Activity -> this
is ContextWrapper -> baseContext.getActivity()
else -> null
}
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.
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))
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.