簡體   English   中英

如何在 Jetpack Compose 中使用 Coil 制作首字母圖標

[英]How to make initials icons using Coil in Jetpack Compose

所以我使用 Coil 庫進行圖像處理,我注意到在占位符中它只需要一個整數。 但是,如果用戶沒有頭像或出現任何錯誤顯示縮寫,我想顯示縮寫,如下圖所示。 問題是,我是 Jetpack Compose 的新手,不確定如何實現這一目標。 請參閱下面的代碼。

在此處輸入圖像描述

我有這張帶有圖標的卡片,還有一些詳細信息我的個人資料卡片

ProfileCard( 
    personName = String.format("%s %s", e.firstName, e.lastName),
    personC = entity.program ?: "", 
    painter = rememberAsyncImagePainter(model = getProfileAvatar(entity.id)),
    onCardClick = {})

我的getProfileAvatar()

private fun getProfileAvatar(id: String) : ImageRequest {
    val url = ServiceAPI.photoUrl(id) 
    return ImageRequest.Builder(requireContext()) 
        .data(url) 
        .addHeader() ) 
        .build() }

感謝反饋,我確實看到了一些帖子,但沒有解決 Jetpack 部分。

您可以為此使用線圈的SubcomposeAsyncImage 它允許您使用任何可組合的 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()
    }
}

例子:

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 沒有對可組合占位符的內置支持。
但是你有不同的選擇。

您可以使用使用painter.stateSubcomposeAsyncImage來定義不同的可組合項:

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()
    }

在此處輸入圖像描述

AsyncImage中的placeholder參數也接受Painter 您可以定義自定義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)
)

在哪里:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM