- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
根据设计,我们的 ImageView 应该在 View 顶部添加一个标签。此标签应包含文本,例如“50%”,表示图片中的商品已打折 50%。
如何在 Jetpack Compose 中的现有 ImageView 之上绘制这样的标签/丝带?
编辑:使用的图像是来自 URL 的图像,如果这很重要,当前正在使用 Coil 的“AsyncImage”加载
最佳答案
解决这个问题需要简单的数学运算、带旋转功能的 Drawscope、用于测量文本宽度和高度的 TextMeasurer。如果您希望将这些作为修饰符,则组成修饰符。构建一个具有纯色背景的另一个具有微光效果。您可以在应用这些修饰符之前检查 painter.state 是否成功。
结果
修改器实现
fun Modifier.drawDiagonalLabel(
text: String,
color: Color,
style: TextStyle = TextStyle(
fontSize = 18.sp,
fontWeight = FontWeight.SemiBold,
color = Color.White
),
labelTextRatio: Float = 7f
) = composed(
factory = {
val textMeasurer = rememberTextMeasurer()
val textLayoutResult: TextLayoutResult = remember {
textMeasurer.measure(text = AnnotatedString(text), style = style)
}
Modifier
.clipToBounds()
.drawWithContent {
val canvasWidth = size.width
val canvasHeight = size.height
val textSize = textLayoutResult.size
val textWidth = textSize.width
val textHeight = textSize.height
val rectWidth = textWidth * labelTextRatio
val rectHeight = textHeight * 1.1f
val rect = Rect(
offset = Offset(canvasWidth - rectWidth, 0f),
size = Size(rectWidth, rectHeight)
)
val sqrt = sqrt(rectWidth / 2f)
val translatePos = sqrt * sqrt
drawContent()
withTransform(
{
rotate(
degrees = 45f,
pivot = Offset(
canvasWidth - rectWidth / 2,
translatePos
)
)
}
) {
drawRect(
color = color,
topLeft = rect.topLeft,
size = rect.size
)
drawText(
textMeasurer = textMeasurer,
text = text,
style = style,
topLeft = Offset(
rect.left + (rectWidth - textWidth) / 2f,
rect.top + (rect.bottom - textHeight) / 2f
)
)
}
}
}
)
fun Modifier.drawDiagonalShimmerLabel(
text: String,
color: Color,
style: TextStyle = TextStyle(
fontSize = 18.sp,
fontWeight = FontWeight.SemiBold,
color = Color.White
),
labelTextRatio: Float = 7f,
) = composed(
factory = {
val textMeasurer = rememberTextMeasurer()
val textLayoutResult: TextLayoutResult = remember {
textMeasurer.measure(text = AnnotatedString(text), style = style)
}
val transition = rememberInfiniteTransition()
val progress by transition.animateFloat(
initialValue = 0f,
targetValue = 1f,
animationSpec = infiniteRepeatable(
animation = tween(3000, easing = LinearEasing),
repeatMode = RepeatMode.Reverse
)
)
Modifier
.clipToBounds()
.drawWithContent {
val canvasWidth = size.width
val canvasHeight = size.height
val textSize = textLayoutResult.size
val textWidth = textSize.width
val textHeight = textSize.height
val rectWidth = textWidth * labelTextRatio
val rectHeight = textHeight * 1.1f
val rect = Rect(
offset = Offset(canvasWidth - rectWidth, 0f),
size = Size(rectWidth, rectHeight)
)
val sqrt = sqrt(rectWidth / 2f)
val translatePos = sqrt * sqrt
val brush = Brush.linearGradient(
colors = listOf(
color,
style.color,
color,
),
start = Offset(progress * canvasWidth, progress * canvasHeight),
end = Offset(
x = progress * canvasWidth + rectHeight,
y = progress * canvasHeight + rectHeight
),
)
drawContent()
withTransform(
{
rotate(
degrees = 45f,
pivot = Offset(
canvasWidth - rectWidth / 2,
translatePos
)
)
}
) {
drawRect(
brush = brush,
topLeft = rect.topLeft,
size = rect.size
)
drawText(
textMeasurer = textMeasurer,
text = text,
style = style,
topLeft = Offset(
rect.left + (rectWidth - textWidth) / 2f,
rect.top + (rect.bottom - textHeight) / 2f
)
)
}
}
}
)
用法
Column(
modifier = Modifier
.background(backgroundColor)
.fillMaxSize()
.padding(20.dp)
) {
val painter1 = rememberAsyncImagePainter(
model = ImageRequest.Builder(LocalContext.current)
.data("https://www.techtoyreviews.com/wp-content/uploads/2020/09/5152094_Cover_PS5.jpg")
.size(coil.size.Size.ORIGINAL) // Set the target size to load the image at.
.build()
)
Image(
modifier = Modifier
.fillMaxWidth()
.aspectRatio(4 / 3f)
.then(
if (painter1.state is AsyncImagePainter.State.Success) {
Modifier.drawDiagonalLabel(
text = "50%",
color = Color.Red
)
} else Modifier
),
painter = painter1,
contentScale = ContentScale.FillBounds,
contentDescription = null
)
Spacer(modifier = Modifier.height(10.dp))
val painter2 = rememberAsyncImagePainter(
model = ImageRequest.Builder(LocalContext.current)
.data("https://i02.appmifile.com/images/2019/06/03/03ab1861-42fe-4137-b7df-2840d9d3a7f5.png")
.size(coil.size.Size.ORIGINAL) // Set the target size to load the image at.
.build()
)
Image(
modifier = Modifier
.fillMaxWidth()
.aspectRatio(4 / 3f)
.then(
if (painter2.state is AsyncImagePainter.State.Success) {
Modifier.drawDiagonalShimmerLabel(
text = "40% OFF",
color = Color(0xff4CAF50),
labelTextRatio = 5f
)
} else Modifier
),
painter = painter2,
contentScale = ContentScale.FillBounds,
contentDescription = null
)
}
@Composable
private fun RibbonSample() {
val text = "50%"
val textMeasurer = rememberTextMeasurer()
val style = TextStyle(
fontSize = 18.sp,
fontWeight = FontWeight.SemiBold,
color = Color.White
)
val textLayoutResult: TextLayoutResult = remember {
textMeasurer.measure(text = AnnotatedString(text), style = style)
}
Box(
modifier = Modifier
.clipToBounds()
.drawWithContent {
val canvasWidth = size.width
val textSize = textLayoutResult.size
val textWidth = textSize.width
val textHeight = textSize.height
val rectWidth = textWidth * 7f
val rectHeight = textHeight * 1.1f
val rect = Rect(
offset = Offset(canvasWidth - rectWidth, 0f),
size = Size(rectWidth, rectHeight)
)
val translatePos = sqrt(rectWidth / 2f) * sqrt(rectWidth / 2f)
drawContent()
withTransform(
{
rotate(
degrees = 45f,
pivot = Offset(
canvasWidth - rectWidth / 2,
translatePos
)
)
}
) {
drawRect(
Color.Red,
topLeft = rect.topLeft,
size = rect.size
)
drawText(
textMeasurer = textMeasurer,
text = text,
style = style,
topLeft = Offset(
rect.left + (rectWidth - textWidth) / 2f,
rect.top + (rect.bottom - textHeight) / 2f
)
)
}
}
) {
Image(
modifier = Modifier
.fillMaxWidth()
.aspectRatio(4 / 3f),
painter = painterResource(id = R.drawable.landscape1),
contentScale = ContentScale.FillBounds,
contentDescription = null
)
}
}
关于android - 如何在 Jetpack Compose 中向 ImageView 添加对角色带?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74742032/
我在 iPhone 上遇到了 openGL 问题,我确信一定有一个简单的解决方案! 当我加载纹理并显示它时,我得到了很多我认为所谓的“色带”,其中颜色,特别是渐变上的颜色,似乎会自动“优化”。 只是为
Android Activity 或 OpenGl 中出现 strip 图像的可能解决方案是什么。 请看下面的答案。 希望对你有帮助 最佳答案 色带已解决 ooooooooooyyyyyyyeaaaa
我有一个 working 'css ribbon tag' 但是,HTML 非常丑陋:
我想创建像这张图片(图片的红色部分)一样的丝带效果: 当我尝试创建带边框的箭头效果时,对象的形状完全被破坏了: HTML代码: Kategorija 到目前为止的 CSS 代码(没有尝试创建箭头):
在应用于正在进行的应用程序之前,我正在试验一些奇特的 CSS 效果,我遇到了 Ribbons . 就其本身而言,它工作得很好,但我不会按照生成器的建议使用固定元素,所以我在主框中添加了一个图像 但是,
我正在尝试使用 ggplot2 绘制热图,并且我想调整颜色栏的大小并增加字体。 这是代码的相关部分: g <- ggplot(data=melt.m) g2 <- g+geom_rect(aes(xm
一段时间以来,我一直在使用 this创建 Angular 丝带,到目前为止它一直运行良好: body { margin: 10% } img { border-radius: 0.5vw; }
我尝试创建 MS 功能区按钮图标表单代码。我创建了 32 bpp 的 CImage。 CImage img; img.Create(size, size, 32, CImage::createAlph
我有一个很大的表格,需要将单元格的背景更改为 1 到 6 个色带,就像矩形堆叠在一起(其他信息将出现在单元格内)。虽然这个例子是一个表格,但我猜这适用于任何 DIV。我希望能够(通过动态 javasc
我正在尝试反转这个朝阳可视化的色带。它使用带有标签等的 sunburst 可缩放图表。通常情况下,您只需反转它们正在使用的范围内的值,但我不太明白它是如何在设置中获取这些值的。 这是我使用的配色方案
我是一名优秀的程序员,十分优秀!