gpt4 book ai didi

android - Jetpack Compose 自定义徽章与 CircleShape 的动态文本大小未正确绘制

转载 作者:行者123 更新时间:2023-12-04 23:47:03 27 4
gpt4 key购买 nike

我有一个使用 onMeasure、onLayout 和 OnDraw 用 View 编写的 BadgeView
enter image description here
我正在尝试迁移 this View到 Jetpack Compose。
由于使用 compose 绘制形状更容易,我认为没有必要使用 Canvas 或 Layout完全起作用,但是在计算文本大小之前没有正确设置文本或曲面环绕的大小,并且没有正确绘制圆圈。
还检查了徽章组件,它使用静态尺寸 BadgeWithContentRadius ,因为在我的设计中,大小取决于文本大小,因此无法设置静态大小。

Surface(
shape = CircleShape,
contentColor = Color.White,
color = Color.Red
) {
Text(
text = "0",
modifier = Modifier.padding(4.dp),
fontSize = 34.sp,
)
}
enter image description here
然后尝试使用
var size: Dp by remember { mutableStateOf(40.dp) }

val density = LocalDensity.current

Surface(
shape = CircleShape,
modifier = Modifier.size(size),
contentColor = Color.Yellow,
color = Color.Red
){
Text(
text = "0",
modifier = Modifier.padding(4.dp),
fontSize = 24.sp,
onTextLayout = { textLayoutResult: TextLayoutResult ->
val textSize = textLayoutResult.size
val circleRadius = textSize.width.coerceAtLeast(textSize.height)

size = with(density) {
circleRadius.toDp()
}

println("Size: $size")
}
)
}
两种实现都不起作用,然后尝试使用 Layout
@Composable
private fun Badge(text: String, badgeState: BadgeState, modifier: Modifier = Modifier) {
Surface(shape = CircleShape, color = Color.Red, contentColor = Color.White) {
BadgeLayout(text = text, badgeState = badgeState, modifier = modifier)
}
}

@Composable
private fun BadgeLayout(text: String, badgeState: BadgeState, modifier: Modifier = Modifier) {

var circleRadius = 0
var size: IntSize by remember {
mutableStateOf(IntSize(0, 0))
}

val content = @Composable {

Text(
text = text,
modifier = Modifier.padding(4.dp),
fontSize = 34.sp,
onTextLayout = { textLayoutResult: TextLayoutResult ->
size = textLayoutResult.size
circleRadius = size.width.coerceAtLeast(size.height)
},
)

}

Layout(
modifier = modifier,
content = content
) { measurables: List<Measurable>, constraints: Constraints ->

val placeables = measurables.map { measurable ->
measurable.measure(constraints)
}

println("🔥 Badge: $circleRadius, size: $size")
layout(width = circleRadius, height = circleRadius) {
placeables.first().placeRelative(0, 0)
}
}

}
enter image description here
形状似乎已正确应用,但找不到确切的方法来获取文本大小以将数字设置为 Surface 或 Text 的中心。
一个组件,当它是一个或数字时应该有圆形,然后将它变成 RoundedCornerShape 可以在考虑性能的情况下实现?

最佳答案

我使用 Modifier.layout 做了以下修饰符:

fun Modifier.badgeLayout() =
layout { measurable, constraints ->
val placeable = measurable.measure(constraints)

// based on the expectation of only one line of text
val minPadding = placeable.height / 4

val width = maxOf(placeable.width + minPadding, placeable.height)
layout(width, placeable.height) {
placeable.place((width - placeable.width) / 2, 0)
}
}
用法:
Text(
text,
modifier = Modifier
.background(MaterialTheme.colors.error, shape = CircleShape)
.badgeLayout()
)
结果:

关于android - Jetpack Compose 自定义徽章与 CircleShape 的动态文本大小未正确绘制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69987940/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com