I am working on Jetpack Compose
UI in Android
.
I have a following Box
which shows a Text
.
@Preview
@Composable
fun MyText(modifier: Modifier = Modifier)
{
Box(modifier = Modifier.heightIn(max = 94.dp).widthIn(max = 270.dp)
.clip(shape = RoundedCornerShape(20.dp))
.border(
width = 1.dp,
color = Color.Green,
shape = RoundedCornerShape(20.dp)
)
.padding(horizontal = 20.dp, vertical = 8.dp)) {
Text(
text = "Learn how to use Compose effectively",
overflow = TextOverflow.Ellipsis,
maxLines = 3,
fontSize = 15.sp,
fontWeight = FontWeight.W400,
color = Color.Red
)
}
}
It produces attached output. As you can see, "effectively" shifts to next line due to width constraints but it leaves much empty space after "Compose" in the first line. Is there a way to remove that extra left space so that overall width reduces?
You can try to use the onTextLayout
callback to find out how long the longest line of the actual text is. Then, set the maximum width of the Text
to the longest line length (rounded):
@Preview
@Composable
fun MyText(modifier: Modifier = Modifier) {
val localDensity = LocalDensity.current
var textWidth by remember { mutableIntStateOf(Int.MAX_VALUE) }
Box(
modifier = Modifier
.wrapContentWidth()
.clip(shape = RoundedCornerShape(20.dp))
.border(
width = 1.dp,
color = Color.Green,
shape = RoundedCornerShape(20.dp)
)
.padding(horizontal = 20.dp, vertical = 8.dp)
) {
Text(
modifier = Modifier
.requiredHeightIn(max = 94.dp)
.requiredWidthIn( max =
min(
localDensity.run { textWidth.toDp() },
230.dp
)
),
text = "Learn how to use Compose effectively",
onTextLayout = { textLayoutResult ->
var longestLine = 0f
repeat(textLayoutResult.lineCount) { lineIndex ->
longestLine = max(longestLine, textLayoutResult.getLineRight(lineIndex))
}
textWidth = ceil(longestLine).toInt()
},
overflow = TextOverflow.Ellipsis,
maxLines = 3,
fontSize = 15.sp,
fontWeight = FontWeight.W400,
color = Color.Red
)
}
}
Note that I shifted all the Modifier
s to the Text Composable and also adjusted the maximum width to not include the padding.
Output: