How to handle border and background in compose shape? - android

In the code the image border only on the sides, not on the corners.
for the button, the background goes out of the shape/border.
I only managed to "fix" the button by using a fixed height but I don't understand why a fixed height help and I wonder if there is another way to do this.
#Composable
fun Test(){
Column(modifier = Modifier.padding(5.dp)) {
Image(
painter = painterResource(id = R.drawable.ic_close),
contentDescription = null,
modifier = Modifier
.clip(CircleShape)
.border(1.dp, Color.Red)
.size(20.dp)
)
OutlinedButton(
onClick = { },
border = BorderStroke(1.dp, Color.Red),
shape = RoundedCornerShape(5.dp),
modifier = Modifier
.clip(RoundedCornerShape(5.dp))
.fillMaxWidth()
.background(Color.Green)
) {}
}
}

For the Image, remove the clip modifier and use the shape inside the border parameter:
Image(
painter = painterResource(id = R.drawable.ic_xxx),
contentDescription = null,
modifier = Modifier
//.clip(CircleShape)
.border(1.dp, Color.Red, CircleShape)
.size(20.dp)
)
For the OutlinedButton use the colors attribute to assign the background color instead of the Modifier.background
OutlinedButton(
onClick = { },
border = BorderStroke(1.dp, Color.Red),
shape = RoundedCornerShape(5.dp),
modifier = Modifier
//.clip(RoundedCornerShape(5.dp))
.fillMaxWidth(),
//.background(Color.Green),
colors = ButtonDefaults.outlinedButtonColors(backgroundColor = Green),
)

Related

Jetpack compose - Border for Image reduces padding

#Composable
fun BottomStrip() {
Row(modifier = Modifier
.fillMaxWidth()
.height(70.dp)
.background(color = colorResource(id = R.color.cgux_background_grey)),
horizontalArrangement = Arrangement.End, verticalAlignment = Alignment.CenterVertically) {
Image(
painter = painterResource(id = R.drawable.cgux_ic_keyboard_16),
modifier = Modifier
.width(36.dp)
.height(36.dp)
.border(BorderStroke(1.dp, colorResource(id = R.color.cgux_primary_500_base)))
.padding(5.dp)
.clickable {},
contentDescription = "Expandable Image",
colorFilter = ColorFilter.tint( colorResource(id = R.color.cgux_primary_500_base))
)
}
}
I have a composable function as above . My idea is to align image to right of Row with some padding on all sides of Image.
I also have to create border around image , which I did using border modifier.
The problem I'm facing is when I set border to Image , the padding is lost which means I don't see padding for Image. Image touch right end of the screen.Is there a way we can have padding for border as well.?
Adding the padding before border will solve your problem. Below is the full code.
#Composable
fun BottomStrip() {
Row(modifier = Modifier
.fillMaxWidth()
.height(70.dp)
.background(color = colorResource(id = R.color.cgux_background_grey)),
horizontalArrangement = Arrangement.End, verticalAlignment = Alignment.CenterVertically) {
Image(
painter = painterResource(id = R.drawable.cgux_ic_keyboard_16),
modifier = Modifier
.width(36.dp)
.height(36.dp)
.padding(5.dp)
.border(BorderStroke(1.dp, colorResource(id = R.color.cgux_primary_500_base)))
.padding(5.dp)
.clickable {},
contentDescription = "Expandable Image",
colorFilter = ColorFilter.tint( colorResource(id = R.color.cgux_primary_500_base))
)
}
}
In jetpack compose the order of modifiers is important. Official doc
You can use this solution and add padding before setting size for your image:
#Composable
fun BottomStrip() {
Row(modifier = Modifier
.fillMaxWidth()
.height(70.dp)
.background(color = colorResource(id = R.color.cgux_background_grey)),
horizontalArrangement = Arrangement.End, verticalAlignment = Alignment.CenterVertically) {
Image(
painter = painterResource(id = R.drawable.cgux_ic_keyboard_16),
modifier = Modifier
.padding(5.dp) // padding between Row and Image, you can remove it because you already set size for Image and Row
.border(BorderStroke(1.dp, colorResource(id = R.color.cgux_primary_500_base)))
.padding(5.dp) // padding between border and image
.size(36.dp)
.clickable {},
contentDescription = "Expandable Image",
colorFilter = ColorFilter.tint( colorResource(id = R.color.cgux_primary_500_base))
)
}
}
You can try like below.
#Composable
fun BottomStrip() {
Row(
modifier = Modifier
.fillMaxWidth()
.height(70.dp)
.background(color = Color.Cyan),
horizontalArrangement = Arrangement.End, verticalAlignment = Alignment.CenterVertically
) {
Image(
painter = painterResource(id = R.drawable.ic_visa),
modifier = Modifier
.padding(5.dp)
.border(BorderStroke(1.dp, Color.Red))
.clickable {},
contentDescription = null
)
}
}

Ovelapping icons images in compose

I want to display the icons below so the center one is overlapping.
I am trying to use the Box but not sure how to arrange them so they are overlapping and in the center of the screen.
I have started using a Box with 3 Box stacked on each other. But not sure about how to arrange them so the center slightly overlaps the left and right icons. And slightly higher.
fun SurveyIconScreen() {
Box {
Box(modifier = Modifier
.clip(CircleShape)
.size(22.dp)
.background(color = Color.White),
contentAlignment = Alignment.Center) {
Icon(painter = painterResource(id = R.drawable.ic_star), contentDescription = "Star")
}
Box(modifier = Modifier
.clip(CircleShape)
.size(22.dp)
.background(color = Color.White),
contentAlignment = Alignment.Center) {
Icon(painter = painterResource(id = R.drawable.ic_cart), contentDescription = "Star")
}
Box(modifier = Modifier
.clip(CircleShape)
.size(22.dp)
.background(color = Color.White),
contentAlignment = Alignment.Center) {
Icon(painter = painterResource(id = R.drawable.ic_cart), contentDescription = "Star")
}
}
}
You can apply an offset modifier to overlap the icons.
Also use the zIndex(1f) modifier to drawn the icon in the center on top of all other icons.
Something like:
val shape = RoundedCornerShape(4.dp)
val borderColor = LightGray
Row(
modifier = Modifier.fillMaxWidth().height(70.dp),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically
){
Icon(Icons.Outlined.Star, contentDescription = "Star",
modifier = Modifier
.offset(x = 3.dp)
.size(32.dp)
.border(BorderStroke(1.dp,borderColor), shape)
.background(White)
)
Icon(
Icons.Outlined.ShoppingCart,
contentDescription = "Star",
modifier = Modifier
.zIndex(1f)
.offset(y = -12.dp)
.size(32.dp)
.border(BorderStroke(1.dp,borderColor), shape)
.background(White)
)
Icon(Icons.Outlined.Note, contentDescription = "Star",
modifier = Modifier
.offset(x = -3.dp)
.size(32.dp)
.border(BorderStroke(1.dp,borderColor), shape)
.background(White)
)
}

jetpack compose shadow strange behaviour

I am trying to build an text field with shadow outside
This is the result I achieved so on.
But if you zoom in the picture you will see some rectangle background under white text field (please look at the corners outside of text field, there is a background)
How can I remove that background ?
#Composable
fun MyTextField() {
var text by remember {
mutableStateOf("")
}
Box(
modifier = Modifier
.padding(15.dp)
.shadow(5.dp)
.background(color = Color.White, shape = RoundedCornerShape(10.dp))
.fillMaxWidth()
.height(50.dp),
contentAlignment = Alignment.Center,
) {
TextField(
value = text,
onValueChange = { text = it },
label = { Text(text = "Phone number", color = Color.Gray, fontSize = 14.sp) },
modifier = Modifier
.fillMaxSize()
.background(color = Color.Transparent, shape = RoundedCornerShape(10.dp)),
colors = TextFieldDefaults.textFieldColors(
backgroundColor = Color.Transparent,
focusedIndicatorColor = Color.Transparent,
unfocusedIndicatorColor = Color.Transparent
),
)
}
}
As default the shadow modifier uses a RectangleShape, it is the reason of your issue:
Apply the same shape to the shadow and background modifiers:
val shape = RoundedCornerShape(10.dp)
Box(
modifier = Modifier
.padding(15.dp)
.shadow(
elevation = 5.dp,
shape = shape
)
.background(color = Color.White, shape = shape)
.fillMaxWidth()
.height(50.dp),
contentAlignment = Alignment.Center,
)

How to draw gradient and customize your splash screen in compose?

I am trying to have a splash screen in our application and I got stuck Abit with the jetpack Compose design. So I want to have a background gradient, I am now using the image which does not fit well in the phone and want to center my logo and text in the middle of the screen how can I achieve that. Mostly centering since I have tried the gradient part and I have no success. Here is my code
Here is my background component
#Composable
fun BackgroundComponents(
#DrawableRes backgroundDrawableRes: Int,
contentDescription: String?,
modifier: Modifier = Modifier,
painter: Painter,
alignment: Alignment = Alignment.Center,
) {
Box(
modifier = modifier
) {
Image(
painter = painterResource(id = backgroundDrawableRes),
contentDescription = contentDescription,
modifier = modifier.matchParentSize()
)
Box(
contentAlignment = Alignment.Center
) {
Image(
painter = painter,
contentDescription = contentDescription,
alignment = alignment
)
}
Text(
modifier =
modifier.padding(top = 36.dp),
text = "Hello and welcome to our app",
color = (colorResource(id = R.color.white)),
fontSize = 16.sp,
)
}
}
This is how I am calling it on the Screen
#Composable
fun Splash(modifier: Modifier = Modifier) {
Column(modifier = modifier.fillMaxSize()) {
BackgroundComponents(
backgroundDrawableRes = R.drawable.ic_launcher_foreground,
contentDescription = "",
modifier = modifier.fillMaxSize(),
painter = painterResource(id = coil.base.R.drawable.notification_bg)
)
}
}
I would like to push the icon and text in the middle and centered, also instead of using an image can I draw that gradient?
You can apply the gradient to the parent Box as background modifier and then just apply the expected alignment to the composable inside the Box.
Something like:
Box(
modifier = Modifier
.fillMaxSize()
.background(
Brush.horizontalGradient(
colors = listOf(
Color.Blue,
Teal200
)
)
),
contentAlignment = Alignment.Center
) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Image(
painter = painterResource(id = R.drawable.xx),
contentDescription = "contentDescription",
)
Spacer(Modifier.height(36.dp))
Text(
text = "Hello and welcome to our app",
color = White,
fontSize = 16.sp,
)
}
}

No ripple effect in Jetpack Compose

There is no ripple effect when I click on MyBox() I've added MyTheme(){} to main #Composable screen but it doesn't work. Is something missing?
#Composable
private MyBox(onClickInvoked: () -> Unit) {
MyAppTheme(isSystemInDarkTheme()) {
Box(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.clip(RoundedCornerShape(10.dp))
.background(MaterialTheme.colors.onBackground)
.clickable(onClick = { onClickInvoked.invoke() })
.padding(horizontal = 10.dp, vertical = 15.dp)
) {
Text(
text = "My text",
modifier = Modifier
.align(Alignment.CenterStart)
.padding(end = 95.dp)
.wrapContentWidth()
.wrapContentHeight(),
color = MaterialTheme.colors.primary
)
Image(
painter = painterResource(R.drawable.icon),
modifier = Modifier
.align(Alignment.CenterEnd)
.padding(end = 20.dp)
.size(60.dp)
)
}
}
}
With compose 1.0.5, I see the default indication after set clickable is
LocalIndication.current. And LocalIndication.current is PlatformRipple. Therefore, after you set clickable to your Box, it will have ripple effect.
In your case, I think the ripple effect won't display because your Box background is too dark (normally MaterialTheme.colors.onBackground is black on Light theme)
I think you can change the ripple effect color to make it easy to see.
Surface(
onClick = { onClickInvoked.invoke() },
modifier = Modifier.fillMaxWidth(),
shape = RoundedCornerShape(10.dp),
color = MaterialTheme.colors.onBackground, // normally it is black on Light theme
indication = rememberRipple(color = Color.White) // color for your ripple, you can use other suitable MaterialTheme.colors for your case to support Light/Dark mode
) {
Box(modifier = Modifier.padding(horizontal = 10.dp, vertical = 15.dp)) {
// your Box content
...
}
}
There is a Modifier.indication but after testing I see it not working with Modifier.clickable so I use Surface
I don't really know if there is a problem with your theme. I try to pass the material theme, and the ripples will display normally
MaterialTheme() {
Box(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.clip(RoundedCornerShape(10.dp))
.background(MaterialTheme.colors.secondary)
.clickable(onClick = { t = "My text" })
.padding(horizontal = 10.dp, vertical = 15.dp)
) {
Text(
text = t,
modifier = Modifier
.align(Alignment.CenterStart)
.padding(end = 95.dp)
.wrapContentWidth()
.wrapContentHeight(),
color = MaterialTheme.colors.primary
)
Image(
painter = painterResource(R.drawable.ic_launcher_foreground),
modifier = Modifier
.align(Alignment.CenterEnd)
.padding(end = 20.dp)
.size(60.dp),
contentDescription = ""
)
}
}

Categories

Resources