Reputation: 183
I was trying to create custom text rendering composable using the the Canvas composable. However, I don't understand how TextMeasurer is calculating the final height of the composable.
Here is a minimal example of what I have tried till now.
@Composable
fun ShyText(
text: String,
modifier: Modifier = Modifier
) {
val textMeasurer = rememberTextMeasurer()
val measuredText =
textMeasurer.measure(
AnnotatedString(text),
overflow = TextOverflow.Ellipsis,
constraints = Constraints.fixedWidth(1080),
style = TextStyle(
fontSize = 18.sp,
)
)
Canvas(
Modifier
.fillMaxWidth()
.height(measuredText.size.height.dp) //I think the bug is coming from this line.
.background(Color.DarkGray)
) {
drawText(
measuredText,
)
}
}
Here is how the composable is used.
ShyTextTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
Column(Modifier.padding(innerPadding)) {
ShyText(
text = sampletext,
)
Text("text")
}
}
}
I am trying to render without the blank space above "text" and the final line of the paragraph. I would like to know why the blank space is being rendered. (The grey background is just for testing)
Upvotes: 1
Views: 65
Reputation: 67238
That's not bug. What's returned from measuredText.size.height
is in pixels. But you set height in dp directly from pixel value by adding dp end of it. density independent pixels are calculated with pixel value / density
. If you get 200px from measured height on a device with 2.0 density it should be 100.dp, on a device with 4.0 density it should be 50.dp.
You just need to change it to
val density = LocalDensity.current
val heightDp = with(density){measuredText.size.height.toDp()}
Canvas(
Modifier
.fillMaxWidth()
.height(heightDp) //I think the bug is coming from this line.
.background(Color.DarkGray)
) {
drawText(
measuredText,
)
}
This is how conversion is done with toDp()
/** Convert a [Float] pixel value to a Dp */
@Stable
fun Float.toDp(): Dp = (this / density).dp
Upvotes: 1
Reputation: 59
I don't not if this might help, I'm currently learning android studio, language in use is java. If there is a view on the xml file you just drop the element you wish to place, e.g text, button e.t.c, after which you place your mouse on the borders of the element and move an arrow line toward the edge of the window(phone) for both sides and it will usually be centered. It doesn't have to be the edge it could also be an element.
Upvotes: 0