[英]How to make initials icons using Coil in Jetpack Compose
So I am using the Coil library for our image processing and I noticed in the place holder it only takes an int.所以我使用 Coil 库进行图像处理,我注意到在占位符中它只需要一个整数。 I want however to display initials if a user does not have an avatar or incase of any error show initials, like this image see below.
但是,如果用户没有头像或出现任何错误显示缩写,我想显示缩写,如下图所示。 Problem is, I am new in jetpack compose and not sure how I can achieve this.
问题是,我是 Jetpack Compose 的新手,不确定如何实现这一目标。 See my code below.
请参阅下面的代码。
I have this card that has icon, and some details my Profile Card我有这张带有图标的卡片,还有一些详细信息我的个人资料卡片
ProfileCard(
personName = String.format("%s %s", e.firstName, e.lastName),
personC = entity.program ?: "",
painter = rememberAsyncImagePainter(model = getProfileAvatar(entity.id)),
onCardClick = {})
My getProfileAvatar()
我的
getProfileAvatar()
private fun getProfileAvatar(id: String) : ImageRequest {
val url = ServiceAPI.photoUrl(id)
return ImageRequest.Builder(requireContext())
.data(url)
.addHeader() )
.build() }
Will appreciate feedback, I did see a couple of post, but don't address the Jetpack part.感谢反馈,我确实看到了一些帖子,但没有解决 Jetpack 部分。
You can use coil's SubcomposeAsyncImage
for that.您可以为此使用线圈的
SubcomposeAsyncImage
。 It allows you to use any composable function as a placeholder/error state:它允许您使用任何可组合的 function 作为占位符/错误 state:
SubcomposeAsyncImage(
model = getProfileAvatar()
) {
val state = painter.state
if (state is AsyncImagePainter.State.Loading || state is AsyncImagePainter.State.Error) {
Text(text = "NG")
} else {
SubcomposeAsyncImageContent()
}
}
Example:例子:
val personName by remember{ mutableStateOf(String.format("%s %s", entity.firstName, entity.lastName)) }
val painter = rememberAsyncImagePainter(
model = ImageRequest.Builder(LocalContext.current)
.allowHardware(false)
.data("https://xxxx.xxxx.user_avatar.jpg")
.size(Size.ORIGINAL)
.build()
)
val isErrorState = painter.state is AsyncImagePainter.State.Error
val textMeasure = rememberTextMeasurer()
val textLayoutResult = textMeasure.measure(text = buildAnnotatedString { append(personName) }, style = TextStyle(color = Color.White, fontSize = 16.sp))
ProfileCard(
modifier = Modifier.drawBehind {
if(isErrorState) {
drawText(textLayoutResult = textLayoutResult)
}
},
personName = personName,
personC = entity.program ?: "",
painter = rememberAsyncImagePainter(model = getProfileAvatar(entity.id)),
onCardClick = {}
)
Coil has no built-in support for composable placeholders. Coil 没有对可组合占位符的内置支持。
However you have different options.但是你有不同的选择。
You can use the SubcomposeAsyncImage
using the painter.state
to define different Composables:您可以使用使用
painter.state
的SubcomposeAsyncImage
来定义不同的可组合项:
SubcomposeAsyncImage(
model = url,
contentDescription = "contentDescription",
contentScale = ContentScale.Crop,
modifier = Modifier.clip(CircleShape)
) {
val state = painter.state
if (state is AsyncImagePainter.State.Loading || state is AsyncImagePainter.State.Error) {
//text with a background circle
Text(
modifier = Modifier
.padding(16.dp)
.drawBehind {
drawCircle(
color = Teal200,
radius = this.size.maxDimension
)
},
text = "NG",
style = TextStyle(color = Color.White, fontSize = 20.sp)
)
} else {
SubcomposeAsyncImageContent()
}
Also the placeholder
parameter in the AsyncImage
accepts a Painter
. AsyncImage
中的placeholder
参数也接受Painter
。 You can define your custom TextPainter
您可以定义自定义
TextPainter
AsyncImage(
model = ImageRequest.Builder(LocalContext.current)
.data(url)
.build(),
placeholder = TextPainter(
circleColor= Teal200,
textMeasurer = rememberTextMeasurer(),
text="NG",
circleSize = Size(200f, 200f)
),
contentDescription = null,
contentScale = ContentScale.Crop,
modifier = Modifier.padding(16.dp)
)
where:在哪里:
class TextPainter(val circleColor: Color,
val circleSize : Size,
val textMeasurer: TextMeasurer,
val text : String,
) : Painter() {
val textLayoutResult: TextLayoutResult =
textMeasurer.measure(
text = AnnotatedString(text),
style = TextStyle(color = Color.White, fontSize = 20.sp)
)
override val intrinsicSize: Size get() = circleSize
override fun DrawScope.onDraw() {
//the circle background
drawCircle(
color = circleColor,
radius = size.maxDimension/2
)
val textSize = textLayoutResult.size
//The text
drawText(
textLayoutResult = textLayoutResult,
topLeft = Offset(
(this.size.width - textSize.width) / 2f,
(this.size.height - textSize.height) / 2f
)
)
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.