Hi I want to create a speechbubble. I created an i...
# compose
t
Hi I want to create a speechbubble. I created an image and a text inside a Box. I want the speechbubble-image (vector image) to adapt it's size to the text-size. To do that I would have to measure the size of the text and apply it to the image. What would be the correct approach to that? Any hints?
b
You probably just need to use an intrinsic size on your image. https://developer.android.com/jetpack/compose/layouts/intrinsic-measurements
s
OnTextLayout callback on Text composable
2
👌 1
t
Thank you for your answers! I appreciate your help with that issue. That's how I solved it for now. Feedback welcomed! That's the speechbubble-composable
Copy code
@Composable
fun Speechbubble(
    width: Dp,
    height: Dp,
    text: String,
    onLayoutSizeChanged: (width: Dp, height: Dp) -> Unit
) {
    Box(
        modifier = Modifier.width(200.dp).padding(10.dp),
    ) {

        val density = LocalDensity.current

        Image(
            painterResource(R.drawable.ic_speechbubble), stringResource(
                R.string.speechbubble
            ),
            modifier = Modifier.size(
                width,
                height
            ),
            contentScale = ContentScale.FillBounds
        )
        Text(
            modifier = Modifier.padding(20.dp, 10.dp, 20.dp, 0.dp),
            text = text,
            color = MaterialTheme.colors.onSurface,
            onTextLayout = { result ->

                var maxLineWidth = 0f
                for (i in 0 until result.lineCount) {
                    val current = result.getLineRight(i)
                    if (current > maxLineWidth)
                        maxLineWidth = current
                }

		val maxLineWidthDp = with(density) {
                    maxLineWith.toDp() + 40.dp
                }

                val lastLineBottom = with(density) {
                    result.getLineBottom(result.lineCount - 1).toDp() + 40.dp
                }

            
                onLayoutSizeChanged(
                    maxLineWidthDp,
                    lastLineBottom,
                )
            }

        )
    }
}
In the calling composable I update the state of width and height (in my case it's a list because I've multiple bubbles in a column) State-Variables
Copy code
val textWidth = remember { mutableStateListOf<Dp>() }
 val textHeight = remember { mutableStateListOf<Dp>() }
Updating State-Variables
Copy code
items.forEachIndexed { index, trainingItem ->
                          
                                    Speechbubble(
                                        width = textWidth[index],
                                        height = textHeight[index],
                                        text = stringResource(trainingItem.question),
                                        onLayoutSizeChanged = { width, height ->
                                            textWidth[index] = width
                                            textHeight[index] = height
                                        }
                                    )
                                   
                                }
👍 1