What is the equivalent of layer-list in jetpack compose? - android

What is the equivalent of layer-list in jetpack compose?
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/lightGray" />
<item android:drawable="#drawable/transp_01" />
</layer-list>
I want to get an image like the one shown to use as a background for all my screens

You can draw it easily in compose. With Box you can place any amount of images on top of each other same as layer list can do. So generally specking, you could use something like this:
Box {
// replace any color item from the layer list with box with background:
Box(
modifier = Modifier
.background(Color.LightGray)
.matchParentSize()
)
// replace drawable item with Image:
Image(
painter = painterResource(id = R.drawable.my_image),
contentDescription = "...",
)
}
But in your case, it looks like you only need one image, and you can set a background color for it. Since you need to reuse it in your application, you can move it to a separate view, for example like this:
#Composable
fun BackgroundView(modifier: Modifier) {
Image(
painter = painterResource(id = R.drawable.transp_01),
contentDescription = "...",
modifier = modifier.background(Color.LightGray)
)
}
Then set it as background to any screen like this:
#Composable
fun SomeScreen() {
Box(Modifier.fillMaxSize()) {
BackgroundView(Modifier.matchParentSize())
// screen content
}
}

Related

Jetpack Compose with Resizable Background Image

Currently, I'm a bit stuck on having a resizable drawable in the background of a card.
Card(
modifier,
shape = RoundedCornerShape(8.dp),
elevation = 6.dp
) {
Image(
painterResource(...),
contentScale = ContentScale.FillWidth,
contentDescription = null,
modifier = Modifier.fillMaxWidth()
)
Box() {
Surface(
color = Color.Transparent,
contentColor = Color.White
) {
Column(Modifier.padding(24.dp)) {
Spacer(Modifier.height(16.dp))
Text(...)
Spacer(Modifier.height(16.dp))
Text(...)
Spacer(Modifier.height(8.dp))
Text(...)
Spacer(Modifier.height(16.dp))
Button(...))
}
}
}
}
What I really am trying to get is the image to resize accordingly to the contents of the card...but not doing that. Basically, it doesn't matter if the image is cropped, but I'm trying to make it fill the card. Right now, since I have FillWidth, on bigger screens like tablets, there is a large unused space at the bottom of the card. Any help would be much appreciated!
Tried replacing the whole card with a box instead, didn't work, different permutations of contentscale also did not help.

Changing card elevation is changing card color in Jetpack compose with Material 3

I am using the Card composable and I want it to be colored white.
But when I add some elevation to it, it changes color to more like the primaryContainer color.
I have seen documentation where they have somehting called as elevationOverlay. But couldn't find an example which says how to use it.
Here is my code:
Card(
modifier = Modifier.padding(top = 16.dp),
colors = CardDefaults.cardColors(containerColor = White),
elevation = CardDefaults.cardElevation(defaultElevation = 2.dp)
) {
}
I do know I can use Elevated card instead of card, but there is same problem with elevated card as well.
Also, this is a special case so I am applying the color manually
To resolve the issue of changing card color when modifying the card elevation in Jetpack Compose with Material Design 3, you can use the background modifier and pass it a Color object to set the desired color. Additionally, you can use the elevationOverlay parameter to set the overlay color.
Here's an updated example of your code:
Card(
modifier = Modifier.padding(top = 16. dp)
.background(color = Color.White),
elevation = CardDefaults.cardElevation(defaultElevation = 2. dp),
elevationOverlay = Color.White
) {}
After trying multiple ways found out that there is no way to override this except for to look at the Card.kt file from SDK and create something similar but disable the tonalColor(Thanks for hint #ianhanniballake that it is using tonalelevation)
Following code should do the work, until overriding is officially supported:
#Composable
fun CardWithoutTonalElevation(
modifier: Modifier = Modifier,
shape: Shape = CardDefaults.shape,
colors: Color = White,
border: BorderStroke? = null,
elevation: Dp = 0.dp,
content: #Composable ColumnScope.() -> Unit = {}
) {
Surface(
modifier = modifier,
shape = shape,
color = colors,
tonalElevation = 0.dp,
shadowElevation = elevation,
border = border,
) {
Column(content = content)
}
}

How to make transparent background in Box jetpack compose

I want to make transparent color of Box in jetpack compose. I tried but it makes white background. Can someone guide me on this?
#Composable
fun OnContentLoading() {
Box(
modifier = Modifier
.fillMaxSize()
.background(Color.Transparent)
) {
CircularProgressIndicator(
modifier = Modifier.align(Alignment.Center),
color = Aqua
)
}
}
#Preview(showBackground = true)
#Composable
fun PreviewOnContentLoading() {
OnContentLoading()
}
Output
background(Color.Transparent)
This or Color.Unspecified draws nothing but Color(0x00000000)
for a transparent background you need to set first two digits between 01 and ff and other six digits are RRGGBB basically it's AARRGGBB

How to draw border depending of color of loaded image?

I load the image by url using the coil library.
After loading I need to draw a border around the image depending of background color of uploaded picture.
For example, if I loaded the picture with white background, I need to set black border.
val painter =
rememberAsyncImagePainter(
ImageRequest.Builder(LocalContext.current)
.data(data = imageUrl)
.apply(block = fun ImageRequest.Builder.() {
crossfade(true)
allowHardware(false)
}).build()
)
val painterState = painter.state
Image(
painter = painter,
contentDescription = null,
modifier = Modifier
.padding(start = 20.dp, top = 20.dp)
.width(130.dp)
.height(68.dp)
)
When painter.state is Succes, i'm picking the color of loaded drawable with Palette library.
How can I access to image after successful loading and draw the border in needed color?
I assume you mean
by How can I access to image after successful
exact bounds of area is ImageBitmap drawn inside Image with ContentScale. If that's the issue i built a library that returns exact bounds and which section of image is drawn but since i'm not sure not adding sample with it. If you don't need exactly the bounds check the answer below
You can define a Color with var color by remember {mutableStateOf(Color.Unspecified)
Modifier.border(x.dp, color) will be recomposed when this color changes. After getting desired color from Palette Api if you set color = colorVibrant for instance, you will be able to draw border around your Image with correct dimensions.
State check here is for creating a producible sample
val painter =
rememberAsyncImagePainter(
ImageRequest.Builder(LocalContext.current)
.data(data = "https://source.unsplash.com/pGM4sjt_BdQ")
.apply(block = fun ImageRequest.Builder.() {
crossfade(true)
allowHardware(false)
}).build()
)
var color by remember { mutableStateOf(Color.Unspecified) }
val painterState = painter.state
if (painterState is AsyncImagePainter.State.Success) {
color = Color.Red
}
Column() {
Spacer(Modifier.height(50.dp))
Text("PainterState State: ${painterState.painter}")
Image(
painter = painter,
contentDescription = null,
modifier = Modifier
.padding(start = 20.dp, top = 20.dp)
.border(2.dp, color)
.width(300.dp)
.height(268.dp)
)
}

How to make a surface background half transparent in jetpack compose, but not the content?

I want to achieve this layout:
In XML I would add an image in a relative layout with match_parent attributes, then a view with a black half-transparent background set to match_parent as well, then the content.
In compose I made this composeable:
#Composable
fun ImageCover(resourceId: Int, alpha: Float = 0.5f, content: #Composable () -> Unit) {
Box(modifier = Modifier.fillMaxSize()) {
Image(
painter = painterResource(id = resourceId),
contentDescription = null,
modifier = Modifier.fillMaxSize(),
contentScale = ContentScale.Crop
)
Surface(
color = Color.Black, modifier = Modifier
.fillMaxSize()
.alpha(alpha)
) {
content()
}
}
}
But the problem is alpha is applied to the surface and its content. So no matter what I put in the content, even if it's another surface with a background, will also be half transparent. Here, for example, the two sentences and two components at the bottom will be half transparent as well.
The background color of the Surface is based on the color attribute.
Apply the alpha to the color property instead of the Modifier.
Something like:
Surface(
color = Color.Black.copy(alpha = 0.6f),
modifier = Modifier.fillMaxSize()
){
//....
}

Categories

Resources