How to set gradient background in TopAppBar using Jetpack Compose - android

I want to set the gradient background of my TopAppBar:
My code:
TopAppBar(
modifier = Modifier.background(
Brush.horizontalGradient(
colors = listOf(
Color.Red,
Color.Green
)
)
),
title = { Text("UI Components") },
backgroundColor = Color.Transparent
)
Result:
I found this post: Jetpack Compose Button with gradient background? for button - so I set backgroundColor transparent and custom background via a modifier. Sadly in my case, there is an additional shadow around text which I don't know how to remove. What should I change or maybe TopAppBar is just not designed to be used using gradient and I should write something completely custom?

This shadow is caused by default elevation. Set it to zero:
TopAppBar(
modifier = Modifier.background(
Brush.horizontalGradient(
colors = listOf(
Color.Red,
Color.Green
)
)
),
title = { Text("UI Components") },
backgroundColor = Color.Transparent,
elevation = 0.dp
)

In TopAppBar from Material3 like this:
TopAppBar(
modifier = Modifier.background(
Brush.horizontalGradient(
colors = listOf(
Color.Red,
Color.Green
)
)
),
title = { Text("UI Components") },
colors = TopAppBarDefaults.smallTopAppBarColors(containerColor = Color.Transparent, navigationIconContentColor = onPrimaryColor, titleContentColor = onPrimaryColor),
)
notice of containerColor = Color.Transparent

Related

Border radius is not changing based on shape when user click on it jetpack compose

Hey guys I am using RoundedCornerShape(4.dp) to my Surface which looks fine. When I tried to click on the item it not showing me 4dp corner in Surface. I tried this stack overflow 1 and stack overflow 2 but nothing works.
binding.itemComposable.setContent {
Column(modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.spacedBy(12.dp)) {
val options = getOptions()
options.forEachIndexed { _, optionText ->
val interactionSource = remember { MutableInteractionSource() }
val isPressed by interactionSource.collectIsPressedAsState()
val backgroundColor = if (isPressed) DuckEggBlue else OffWhite
val textColor = if (isPressed) TealBlue else Slate
val borderWidth = if (isPressed) 1.dp else 0.dp
val borderColor = if (isPressed) Aqua else OffWhite
val clickable = Modifier.clickable(
interactionSource = interactionSource,
indication = rememberRipple(true)
) {
println("Item Click")
}
Surface(
modifier = Modifier
.then(clickable)
.border(borderWidth, borderColor),
shape = RoundedCornerShape(4.dp)
) {
Text(
modifier = Modifier
.fillMaxWidth()
.background(backgroundColor)
.padding(16.dp),
text = optionText,
style = Typography.h3,
fontWeight = FontWeight.Medium,
color = textColor
)
}
}
}
}
Without click on item corner is 4 dp
When I click it's not changing corner
If you want to handle the click on a Surface you have to use the function that accepts an onClick():
Surface(
onClick = {},
shape = RoundedCornerShape(4.dp),
border = BorderStroke(borderWidth,borderColor),
interactionSource = interactionSource
)
Create a variable for shape
val shape = RoundedCornerShape(4.dp)
Use it in Modifier.clip() and Modifier.border() like this,
Surface(
modifier = Modifier
.clip(shape)
.border(
width = borderWidth,
color = borderColor,
shape = shape,
)
.then(clickable),
// shape = shape,
)
shape in border() specifies the shape of the border which by default is RectangleShape. Hence, you are seeing the rectangle border.
shape in clip() changes the shape of the composable before the click action is added. This is to make the ripple effect appear only on the given shape.
Note: Order of modifiers are important.
The shape in the Surface may not be needed after these changes.
If youre using Surface to wrapping the content, try to add a container inside the content for example Box or Column. Then use your Surface only as a shape mask, the background and other content will be flexible as you want.
This is the example
Surface(
modifier = Modifier
.then(clickable)
.border(borderWidth, borderColor),
shape = RoundedCornerShape(4.dp)
) {
Box(modifier = Modifier
.fillMaxWidth()
.fillMaxHeight()
.background(Color.Green)){
Text(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
text = optionText,
style = Typography.h3,
fontWeight = FontWeight.Medium,
color = textColor
)
}
}

Change color of Ripple for IconButton in Jetpack compose

This is not a duplicate of Modify ripple color of IconButton in Jetpack Compose This question was diverted in a different way...
I am trying to change the IconButton ripple colour as follows
IconButton(
modifier = modifier
.indication(
interactionSource = remember { MutableInteractionSource() },
indication = rememberRipple(
bounded = false,
radius = 30.dp,
color = colorResource(id = R.color.error_red)
)
)
.background(colorResource(id = R.color.white), shape = CircleShape),
onClick = { onButtonPressed() }
) {
Icon(
painter = painterResource(R.drawable.ic_busy_small_busy),
contentDescription = buttonContentDesc,
)
}
The ripple colour does not change. It stays dark Grey.
Also, Is there a way to change the alpha of the ripple??

How to remove or reduce padding in Jetpack compose OutlinedButton

Unable to reduce the huge padding in OutlinedButton. Tried contentPadding, modifier padding, etc. Cannot reduce padding for text "apple". Any idea? Should I use any other type of compose component for this?
OutlinedButton(
onClick = {},
border = BorderStroke(1.dp, Color.White),
shape = RoundedCornerShape(12.dp),
contentPadding = PaddingValues(0.dp),
modifier = Modifier
.background(bgColor)
.height(24.dp)
.padding(all = 0.dp),
colors = ButtonDefaults.outlinedButtonColors(backgroundColor = bgColor)) {
Text("apple",
color = Color.White,
style = MaterialTheme.typography.body2,
modifier = Modifier.height(10.dp).padding(vertical = 0.dp), //.background(bgColor),
)
}
Updated after #liveAnyway's answer (thanks!) which appeared to help. After that I removed height from OutlinedButton too - ideally I wanted it like "wrap-content". Once I made that change, I still see the padding. Bottomline I don't want any absolute height specified so that it can work with different font size from system settings.
Row(modifier = Modifier.padding(vertical = 12.dp)) {
OutlinedButton(
onClick = {},
border = BorderStroke(1.dp, Color.White),
shape = RoundedCornerShape(18.dp),
contentPadding = PaddingValues(0.dp),
modifier = Modifier
.background(bgColor)
.padding(all = 0.dp),
colors = ButtonDefaults.outlinedButtonColors(backgroundColor = bgColor)
) {
Text("apple",
color = Color.White,
style = MaterialTheme.typography.body2,
modifier = Modifier.padding(vertical = 0.dp),
)
}
}
Button has default min size modifier. This is done according to Material guidelines, so that the button is easy to hit. If the control size is too small, the user may have problems hitting it, take this into account when changing this parameter.
You can override it by applying defaultMinSize modifier. The 0.dp will be ignored, but starting from 1.dp you will get the desired result:
OutlinedButton(
onClick = { /*TODO*/ },
contentPadding = PaddingValues(),
modifier = Modifier
.defaultMinSize(minWidth = 1.dp, minHeight = 1.dp)
) {
Text(
"Apple",
)
}
Alternatively, you can design your own button without these restrictions:
Surface(
onClick = {
},
shape = MaterialTheme.shapes.small,
color = bgColor,
contentColor = MaterialTheme.colors.primary,
border = ButtonDefaults.outlinedBorder,
role = Role.Button,
) {
Text(
"Apple",
)
}
You have to change the minHeight (default size are MinWidth = 64.dp and MinHeight = 36.dp) and remove the contentPadding with contentPadding = PaddingValues(0.dp):
OutlinedButton(
onClick = {},
border = BorderStroke(1.dp, Color.White),
shape = RoundedCornerShape(12.dp),
contentPadding = PaddingValues(0.dp),
modifier = Modifier.defaultMinSize(
minWidth = ButtonDefaults.MinWidth,
minHeight = 10.dp
)
) {
Text(
"apple",
style = MaterialTheme.typography.body2
)
}

Card VS Box render Difference

Is there an explanation for why this
Card(
modifier =
Modifier
.background(
brush = Brush.horizontalGradient(
colors = listOf(
OrgFarmTheme.colors.secondary,
OrgFarmTheme.colors.onSecondary
)
)
)
.clip(RoundedCornerShape(10))
) {
...
}
renders ,
while
Box(
modifier =
Modifier
.background(
brush = Brush.horizontalGradient(
colors = listOf(
OrgFarmTheme.colors.secondary,
OrgFarmTheme.colors.onSecondary
)
)
)
.clip(RoundedCornerShape(10))
) {
...
}
renders ?
I have tried using the default shape parameter of the Card, but it renders the same.
The Card background color is defined by the backgroundColor property and not by the background modifier. This property also has a default value = MaterialTheme.colors.surface which is applied by default to the Card.
It is the reason of the difference in your code.
If you want to achieve with the Card the same layout of the Box you have to use:
Card(
modifier =
Modifier
.background(
brush = Brush.horizontalGradient(
colors = listOf(
MaterialTheme.colors.secondary,
MaterialTheme.colors.onSecondary
)
)
)
,
backgroundColor = Transparent,
shape = RoundedCornerShape(10),
elevation = 0.dp //it is important to avoid borders
)
If you want a Box with elevation and a gradient as background you can use the shadow modifier:
Box(
modifier =
Modifier
.shadow(12.dp,RoundedCornerShape(10),true)
.background(
brush = Brush.horizontalGradient(
colors = listOf(
MaterialTheme.colors.secondary,
MaterialTheme.colors.onSecondary
)
)
)
.clip(RoundedCornerShape(10))
) {
}

background color on Button in Jetpack Compose

Button(backgroundColor = Color.Yellow) {
Row {
Image(asset = image)
Spacer(4.dp)
Text("Button")
}
}
I can not figure out why I can't use background color on Button.
I followed the Compose Layout codelabs.
There is a problem in backgroundColor and asset in Image().
Use ButtonDefaults which is available in 1.0.0-alpha09 to alpha11
Button(
onClick = {},
colors = ButtonDefaults.buttonColors(backgroundColor = Color.Yellow)
) {
/**/
}
OLD VERSION
The backgroundColor for Button no longer work in 1.0.0-alpha7
Use the below instead
Button(
onClick = {},
colors = ButtonConstants.defaultButtonColors(backgroundColor = Color.Yellow)
) {
/**/
}
You can use the ButtonDefaults.buttonColors
Button(
onClick = { },
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.White,
contentColor = Color.Red)
)
The ButtonConstants.defaultButtonColor is Deprecated at 1.0.0-alpha09 use :
colors = ButtonDefaults.buttonColors(backgroundColor = Color.Yellow)
Update version 1.3.0 :
colors = ButtonDefaults.buttonColors(containerColor = Color.Yellow),
Compose background buttons color
create a variable mainButtonColor and define background Color and content Color
implementation 'androidx.compose.material3:material3:1.0.0-alpha02'
val mainButtonColor = ButtonDefaults.buttonColors(
containerColor = androidx.compose.ui.graphics.Color.Red,
contentColor = MaterialTheme.colorScheme.surface
)
Row {
Button(colors = mainButtonColor, onClick = {}, modifier = Modifier.padding(8.dp)) {
Text(text = "Custom colors")
}
}
Custom Colors
To create a custom color you need the RGB value of that color.
Button(
onClick = { },
colors = ButtonDefaults.buttonColors(
backgroundColor = Color(red = 255, green = 169, blue = 0)
)
) {}
backgroundColor = Color(red = 255, green = 169, blue = 0) is how we change the background color of the button to a custom color
STEP 1: Simple only set bg:
Button(
colors = buttonColors(Color.Red),
onClick = {}
) {
Text(text = "Login")
}
Full set colors:
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.Red,
contentColor = Color.Green,
disabledBackgroundColor = Color.Yellow,
disabledContentColor = Color.Magenta
),
onClick = {}
) {
Text(text = "Login")
}
STEP 2 (optional): but this best practice
Material 2 case:
Color.Red change MaterialTheme.colors.primary
Material 3 case:
Color.Red change MaterialTheme.colorScheme.tertiaryContainer

Categories

Resources