Bradleycorn
05/22/2021, 7:46 PMSubComposeLayout and Intrinsics work together? For example something like the following:
Row(modifier = Modifier.fillMaxWidth.height(IntrinsicSize.Min)) {
BoxWithConstraints(...) {
...
}
}
this currently crashes with an IllegalStateException with a message of
Intrinsic measurements are not currently supported by SubcomposeLayoutAny way to “fix” this?
Zach Klippenstein (he/him) [MOD]
05/22/2021, 8:09 PMBradleycorn
05/22/2021, 8:15 PMRow and use a ConstraintLayout and then I wouldn’t need to use Intrinsics for the height.
I posted the question for 2 reasons:
1. To find out if if this is something that won’t (or can’t) ever be “fixed”, so I need to learn other tools to deal with situations like this, and
2. What those other tools might be.
But yeah, I custom layout might be one of those tools.Zach Klippenstein (he/him) [MOD]
05/22/2021, 10:48 PMBradleycorn
05/24/2021, 3:10 PMBoxWithConstraints to set the fontSize on a Text dynamically based on the Box’s width (it’s a reusable component that can by any size). If I could figure out a (decent) way to do that without SubComposeLayout, it would solve my problems. The other option is to figure out the best way to NOT use Intrinsics for the container’s height. See below for the details on the container.Bradleycorn
05/24/2021, 3:10 PMRow (it’s an item in a Lazy Column). It has several things, but there are 2 that matter. There is a Column in the Row that contains three Text composables, and essentially the `Row`’s height should wrap the Column. Next to the column is a SaddleCloth composable, which is a wrapper for a BoxWithConstraints. The SaddleCloth composable is a reusable component that can be any size, and uses the BoxWithConstraints to set the fontSize on the Text it contains dynamically, based on it’s width. it also has a pretty complex background that is drawn from a Path (to create things like stripes and triangles).
@Composable
fun RunnerRow(runner: Runner, race: Race) {
Row(modifier = Modifier
.fillMaxWidth()
.height(IntrinsicSize.Min)
.padding(end = 8.dp)) {
SaddleCloth(
programNumber = runner.programNumber,
trackType = race.raceId.trackId.trackType,
bettingInterest = runner.bettingInterest,
modifier = Modifier.width(24.dp).fillMaxHeight()
)
Column(
modifier = Modifier
.weight(1F)
.padding(horizontal = 8.dp, vertical = 6.dp)
) {
Text(text = runner.name, fontWeight = FontWeight.Bold)
Text(text = runner.jockey, style = MaterialTheme.typography.caption)
Text(text = runner.trainer, style = MaterialTheme.typography.caption)
}
}
}
And as I mentioned, the SaddleCloth wraps a BoxWithConstraints and sets the fontSize based on it’s width (which is not always fixed. The composable is used in several places with varying sizes).. In the above Row, I want the SaddleCloth to fill the height of the Row (which should be determined by wrapping the Column of 3 Text composables). Using Intrinsics works great for that, except that the SaddleCloth is a BoxWithConstraints, which uses SubComposeLayout.
@Composable
fun SaddleCloth(programNumber: String, trackType: TrackType, bettingInterest: Int, modifier: Modifier = Modifier) {
val saddleCloth = remember(trackType, bettingInterest) { saddleCloths.forRunner(trackType, bettingInterest) }
val boxModifier = when {
modifier.any { it is LayoutModifier } -> modifier
else -> modifier.fillMaxSize()
}
BoxWithConstraints(
modifier = boxModifier
.drawWithCache {
// Draw a background using vector [Path]s based on the saddlecloth type.
onDrawBehind {
when (saddleCloth.type) {
is SaddleClothType.Solid -> drawRect(color = saddleCloth.type.primaryColor)
is SaddleClothType.Triangles -> drawTriangles(
size = size,
topColor = saddleCloth.type.primaryColor,
bottomColor = saddleCloth.type.bottomColor)
is SaddleClothType.VerticalStripes -> drawVerticalStripes(
size = size,
baseColor = saddleCloth.type.primaryColor,
stripeColor = saddleCloth.type.stripeColor)
is SaddleClothType.HorizontalStripes -> drawHorizontalStripes(
size = size,
baseColor = saddleCloth.type.primaryColor,
stripeColor = saddleCloth.type.stripeColor)
}
}
},
contentAlignment = Alignment.Center
) {
val fontSize = maxWidth * 0.4f
Text(
text = programNumber,
textAlign = TextAlign.Center,
fontSize = LocalDensity.current.run { fontSize.toSp() },
fontWeight = FontWeight.Bold,
color = saddleCloth.contentColor)
}
}Bradleycorn
05/24/2021, 3:13 PMSaddleCloth composable renders like this:Bradleycorn
05/24/2021, 3:18 PMZach Klippenstein (he/him) [MOD]
05/24/2021, 4:16 PMZach Klippenstein (he/him) [MOD]
05/24/2021, 4:18 PMBradleycorn
05/24/2021, 4:22 PMwrapContentHeight modifier, and then the SaddleCloth is fine to use SubComposeLayout (since there are no more intrinsics) and can fillMaxHeight and it’ll get measured and composed as shown above … do I have that right?Zach Klippenstein (he/him) [MOD]
05/24/2021, 4:37 PMZach Klippenstein (he/him) [MOD]
05/24/2021, 4:41 PMBradleycorn
05/24/2021, 4:45 PMBradleycorn
05/24/2021, 4:46 PMby explicitly reporting a zero intrinsic heighthow would I do that?
Zach Klippenstein (he/him) [MOD]
05/24/2021, 4:47 PMBradleycorn
05/24/2021, 4:48 PMIntrinsicSize.ZERO or something … thought I was going crazy for a minute there 🙂Zach Klippenstein (he/him) [MOD]
05/24/2021, 4:52 PMBradleycorn
05/24/2021, 5:01 PM