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 :)
You can use the CircleShape
.
You can wrap the Text
with a Box
applying a CircleShape
as background and using the layout
modifier to adapt the dimension of the Box
to the current text.
Something like:
Box(contentAlignment= Alignment.Center,
modifier = Modifier
.background(Color.Black, shape = CircleShape)
.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)
}
}) {
Text(
text = "Hello World",
textAlign = TextAlign.Center,
color = Color.White,
modifier = Modifier.padding(4.dp),
)
}
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.
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!
@Composable
fun Avatar(color: Color) {
Box(
modifier = Modifier
.size(size.Dp)
.clip(CircleShape)
.background(color = color),
contentAlignment = Alignment.Center
) {
Text(text = "Hello World")
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With