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
Related
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)
}
}
I get the following warning information with Code A, why?
Optional Modifier parameter should have a default value of Modifier
Code A
#Composable
fun DisplayIcon(
modifier: Modifier=Modifier.size(24.dp),
icon: ImageVector,
tint: Color = Color.Blue
) {
Icon(icon, null, modifier = modifier, tint = tint)
}
It's just a best practice. Using some other default value might lead to weird situations - imagine you want to use two of this component in a Column:
Column {
DisplayIcon()
DisplayIcon()
}
Everything's fine, but now you want to align one of them:
Column {
DisplayIcon()
DisplayIcon(modifier = Modifier.align(Alignment.End))
}
And suddenly, with no apparent reason, one has different size than the other. So you have to find out from DisplayIcon implementation what's going on, and then probably add .size(24.dp) to your aligned composable as well. But now you want to change the default size, and you have to do so on many different places...
Something like this might be better solution:
#Composable
fun DisplayIcon(
modifier: Modifier = Modifier,
icon: ImageVector,
tint: Color = Color.Blue,
size: Dp = 24.dp,
) {
Icon(icon, null, modifier = modifier.size(size), tint = tint)
}
The library I'm using: "com.google.accompanist:accompanist-placeholder-material:0.23.1"
I want to display a placeholder in the place of (or over) a component when it's in the loading state.
I do the following for a Text:
MaterialTheme() {
var placeholderVisible by remember { mutableStateOf(false) }
LaunchedEffect(Unit) {
while (true) {
delay(1000)
placeholderVisible = !placeholderVisible
}
}
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Box(
modifier = Modifier
.border(1.dp, Color.Red)
.padding(16.dp)
) {
Text(
modifier = Modifier
.then(
if (placeholderVisible) {
Modifier.height(28.dp).width(62.dp)
} else {
Modifier
}
)
.placeholder(
visible = placeholderVisible,
highlight = PlaceholderHighlight.shimmer()
),
text = if (placeholderVisible) "" else "Hello"
)
}
}
}
And I get this:
I want instead that no matter how big I set the placeholder's height or width, it will not participate in any way in the measuring process and, if I want to, to be able to draw itself even over other components (in this case let's say the red border).
As an effect of what I want, the box with red border will always have the dimension as if that Modifier.height(28.dp).width(62.dp) is not there.
I know I can draw outside a component's borders using drawWithContent, specifying the size of a rectangle or a circle (or whatever) to be component's size + x.dp.toPx() (or something like that). But how do I do this with Modifier.placeholder?
Ideally, I would need something like Modifier.placeholder(height = 28.dp, width = 62.dp)
So, with or without this ideal Modifier, the UI should never change (except, of course, the shimmer box that may be present or not).
I think I can pull this off by modifying the source code of this Modifier, but I hope I won't need to turn to that.
Just replace your Text() with below code, maybe conditional Modifier is the issue in above code!
Text(
modifier = Modifier
.size(width = 62.dp, height = 28.dp)
.placeholder(
visible = placeholderVisible,
highlight = PlaceholderHighlight.shimmer()
),
text = if (placeholderVisible) "" else "Hello",
textAlign = TextAlign.Center
)
Coming from SwiftUI, I wanted to create a view of a Text where it has a background of a Circle, where the circle's width/height grow as the text inside Text gets longer.
Since there's no Circle() in Compose like there is in SwifUI, I created just a Spacer instead and clipped it. The code below is using ConstraintLayout because I don't know how I would get the width of the Text in order to set the size of my Circle composable to be the same:
#Composable
fun CircleDemo() {
ConstraintLayout {
val (circle, text) = createRefs()
Spacer(
modifier = Modifier
.background(Color.Black)
.constrainAs(circle) {
centerTo(text)
}
)
Text(
text = "Hello",
color = Color.White,
modifier = Modifier
.constrainAs(text) {
centerTo(parent)
}
)
}
}
I can use a mutableStateOf { 0 } where I update that in an onGloballyPositioned modifier attached to the Text and then set that as the requiredSize for the Spacer, but 1. that seems stupid and 2. the Spacer now draws outside the boundaries of the ConstraintLayout.
Visually I want to achieve this:
How would I go about doing this? Thank you :)
It is also possible to use drawBehind from the modifier of the textView itself such as below:
Text(
modifier = Modifier
.padding(16.dp)
.drawBehind {
drawCircle(
color = red,
radius = this.size.maxDimension
)
},
text = "Hello",
)
of course, you can further customize the radius and other properties as you wish!
You have to calculate the dimension of the background circle depending on the dimension of the text.
You can use a custom modifier based on Modifier.layout:
fun Modifier.circleLayout() =
layout { measurable, constraints ->
// Measure the composable
val placeable = measurable.measure(constraints)
//get the current max dimension to assign width=height
val currentHeight = placeable.height
val currentWidth = placeable.width
val newDiameter = maxOf(currentHeight, currentWidth)
//assign the dimension and the center position
layout(newDiameter, newDiameter) {
// Where the composable gets placed
placeable.placeRelative((newDiameter-currentWidth)/2, (newDiameter-currentHeight)/2)
}
}
Then just just apply it the Text with a background with a CircleShape:
Text(
text = "Hello World",
textAlign = TextAlign.Center,
color = Color.White,
modifier = Modifier
.background(Color.Black, shape = CircleShape)
.circleLayout()
.padding(8.dp)
)
#Composable
fun Avatar(color: Color) {
Box(
modifier = Modifier
.size(size.Dp)
.clip(CircleShape)
.background(color = color),
contentAlignment = Alignment.Center
) {
Text(text = "Hello World")
}
}
Use a background drawable of a black circle inside a transparent color. The background drawable will stretch to fill the view, and circles should stretch well without artifacting.
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()
){
//....
}