I thought `Modifier.requiredSize` would be more ag...
# compose
t
I thought
Modifier.requiredSize
would be more aggressive with forcing the size I passed in, but it looks like the size of the containing component matters more? 🤔
Copy code
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.requiredSize
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.darkColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.singleWindowApplication

@Composable
fun SquareCell(
    text: String,
    size: Dp = 150.dp,
    borderWidth: Dp,
) {
    OutlinedButton(
        shape = RectangleShape,
        border = BorderStroke(borderWidth, Color.Blue),
        onClick = {},
        contentPadding = PaddingValues(0.dp),
        modifier = Modifier
            .wrapContentSize()
    ) {
        val fontHeight = size * (2.0f / 3.0f)
        val fontSize = with(LocalDensity.current) { fontHeight.toSp() }

        Text(
            text = text,
            fontSize = fontSize,
            textAlign = TextAlign.Center,
            modifier = Modifier
                .requiredSize(size = size)
        )
    }
}

fun main() = singleWindowApplication {
    MaterialTheme(colorScheme = darkColorScheme()) {
        Surface {
            Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
                SquareCell(text = "a", borderWidth = 0.dp)
                SquareCell(text = "a", borderWidth = 1.dp)
                SquareCell(text = "a", borderWidth = 10.dp)
                SquareCell(text = "a", borderWidth = 20.dp)
                SquareCell(text = "a", borderWidth = 40.dp)
            }
        }
    }
}
image.png
this seems to be the root cause behind some off-by-a-few-pixel alignment issues I have been seeing
OutlinedButton normally has a 1 dp border which seems to steal from size of the contained Text
I can definitely work around this by explicitly setting the button size as well...
e
requiredSize modifies the size constraints seen by the layout inside of it, but can't override the size constraints requested by the parent layout
here, the child is getting measured with a larger size, then laid out inside a smaller space. compose doesn't clip by default so it just draws outside of the space it has been laid out in
t
so I guess it is still "the required size" but it's just mostly outside
interesting how it still centers it too
e
as it is documented to
t
but yeah I work around this one issue and it seems I still have a second one somewhere, I'm sure there is some other padding I am not aware of and just have to find where it's coming from
image.png
the a looks like the baseline is nearly in the right place but it's 2 pix too high
it was 4 pix too high though so this is an improvement!
actually I think I might know what it is. 😞
aligning things which are inside other things has always been one of those hard things
pretty much just moved where I was calling the baseline alignment modifier
have been adjusting how I set the size of that text box too but setting it smaller didn't fix anything in particular, it just tidies the code up a little
some values seem to break it still
the baseline still aligns though which is nice LOL
it's weird though, that character is also in the search box, which doesn't do anything fancy, and it aligns fine in there
maybe a different font
the odd thing is, I have set the app font to NotoSans in the theme, so I expect that font to be used everywhere, but these characters aren't in that font, so I didn't expect them to render at all, I guess text rendering does some font fallback logic behind the scenes, but only in some situations. when I use it for that large code point cell, for example, it doesn't fall back at all
but inside the TextField it does 🤔
ok in Text the fallback works too, the sole place where it doesn't work is when I'm programmatically querying the font for whether chars exist in there
funnily enough though if I use BasicTextField to render the text - it properly centres it and everything
the sole quirk is that it handles click events
it wouldn't be the first time I have used a text field as a text renderer, but it's still the kind of hack I'd like to avoid