android-jetpack-composealignment

Android Compose - Row with Text and Image - How to keep the Text wrapped without pushing off the Image


I have a single line Row with a Text module followed by an Image module. If the text is long, it pushes off the Image. But if I weight the Text, it solves that issue but then the text block takes up the available space instead of wrapping which is what I want.

With the below code, including the Weight Modifier on the Text, it solves the issue of pushing off the Image. But if the title is short, then the Text doesn't wrap shown here: With weight, long title With weight, short title

But without using Weight, I get the text wrap I want but if there is a long title, I lose the Image shown here: Without weight, long title Without weight, short title

How can I protect the Image AND keep text wrapping?

@Composable
fun TitleAndChevron() {
    Row(
        verticalAlignment = Alignment.CenterVertically,
        modifier = Modifier
            .padding(8.dp)
            .background(color = Color.Black)
            .wrapContentWidth(align = Alignment.Start),
    ) {
        Text(
            text = "The Englishman Who Went Up a Hill But Came Down a Mountain",
            color = Color.White,
            maxLines = 1,
            overflow = TextOverflow.Ellipsis,
            style = MaterialTheme.typography.titleLarge,
            modifier = Modifier
                .padding(8.dp)
                .weight(1f)
        )
        Image(
            painter = painterResource(id = R.drawable.ic_chevron),
            contentDescription = null,
            modifier = Modifier
                .padding(start = 8.dp, end = 8.dp)
                .size(12.dp),
        )
    }
}

Solution

  • The weight modifier has a second parameter called fill, the default value is true, which means that by default the element fills the entire width, but if you use false it only takes the required width, which is what you want.

    @Composable
    fun TitleAndChevron() {
        Row(
            verticalAlignment = Alignment.CenterVertically,
            modifier = Modifier
                .padding(8.dp)
                .background(color = Color.Black)
                .wrapContentWidth(align = Alignment.Start),
        ) {
            Text(
                text = "The Englishman Who Went Up a Hill But Came Down a Mountain",
                color = Color.White,
                maxLines = 1,
                overflow = TextOverflow.Ellipsis,
                style = MaterialTheme.typography.titleLarge,
                modifier = Modifier
                    .padding(8.dp)
                    .weight(1f, fill = false)
            )
            Image(
                painter = painterResource(id = R.drawable.ic_chevron),
                contentDescription = null,
                modifier = Modifier
                    .padding(start = 8.dp, end = 8.dp)
                    .size(12.dp),
            )
        }
    }