I have the following composable.
@Composable
fun Temp() {
Row(
modifier = Modifier
.background(Color.Red)
.height(IntrinsicSize.Min)
.fillMaxWidth()
) {
Text(text = "Hello", fontSize = 10.sp)
Icon(
imageVector = Icons.Default.Star,
contentDescription = "Star",
modifier = Modifier.fillMaxHeight()
)
}
}
The height of icon is not decreasing from 24.dp. Is there any way I can achieve this behavior. I want the icon size to just be the height of the parent row. If the text is large. The icons size is increased. I think it has to be with icon minimum size being 24.dp. How can I make icon smaller?
CodePudding user response:
Your code actually works as expected - that's how intrinsic calculations work.
Compose checks the min height of each view and chooses the maximum of those values. In your case, the min height of the image is related to the intrinsic size of the image, which you cannot control in the case of Icons.Default
.
A possible solution is to use Modifier.layout
. When Compose calculates the intrinsic height, the height constraint will be infinite, in which case you can layout it as a zero size view, so that your text will be the highest. When the intrinsic height is determined, you can measure and position the icon:
Row(
modifier = Modifier
.background(Color.Red)
.height(IntrinsicSize.Min)
.fillMaxWidth()
) {
Text(text = "Hello", fontSize = 10.sp)
Icon(
imageVector = Icons.Default.Star,
contentDescription = null,
modifier = Modifier
.layout { measurable, constraints ->
if (constraints.maxHeight == Constraints.Infinity) {
layout(0, 0) {}
} else {
val placeable = measurable.measure(constraints)
layout(placeable.width, placeable.height) {
placeable.place(0, 0)
}
}
}
)
}
Using Modifier.layout
you can change size of view and its position. Usually you use it like this:
- First parameter,
measurable
is an object on which you can callmeasure
withconstraints
- the secondlayout
parameter.measure
is gonna calculate the size your view will take, takingconstraints
in count. - in
layout
you need to pass the desired view size - usually it can be taken fromplaceable
from the previous step. - inside
layout
you need to callplace
on theplaceable
with the desired offset.
With height(IntrinsicSize.Min)
layout
content is getting called multiple times:
- during the first call(s) max height constraint is equal to
Infinity
, so intrinsic calculations can select the correct size ignoring the parent size. - In the last call max height constraint is equal to the calculated parent intrinsic height.
In my code during first calls, when height constraint is equal to Infinity
, I say that this view has zero size, so it's not counted in intrinsic measurements. When intrinsic height is defined, I can layout it with the final constraints.