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