You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用KamelImage加载图片失败时,如何保持错误图片与成功图片尺寸一致?

问题:Jetpack Compose LazyRow中KamelImage加载失败时错误图片高度不一致

我在Jetpack Compose的LazyRow组件中使用KamelImage加载演员头像图片。当图片加载失败时,会显示一张错误图片,但该错误图片的高度始终与加载成功的图片不一致。请问有什么方法可以让所有图片的高度保持统一?

LazyRow代码

LazyRow(
    state = rememberLazyListState(),
    modifier = Modifier.fillMaxWidth().padding(horizontal = 8.dp),
    horizontalArrangement = Arrangement.spacedBy(8.dp),
    verticalAlignment = Alignment.CenterVertically
) {
    items(
        items = credits.cast.take(9),
        key = { cast ->
            cast.id
        }
    ) { cast ->
        CastItem(
            cast = cast
        ) {
            println("ID is $it")
        }
    }

    item {
        TextButton(
            onClick = {}
        ) {
            Text(
                text = "View More ->", fontSize = 18.sp, color = Color.Black,
                textAlign = TextAlign.Center)
        }
    }
}

子项CastItem代码

fun CastItem(
    cast: Cast,
    modifier: Modifier = Modifier,
    onCastClicked: (id: Int) -> Unit
) {
    Card(
        modifier = modifier
            .fillMaxHeight()
            .clickable {
                onCastClicked(cast.id)
            },
        elevation = 2.dp
    ) {
        Column(
            modifier = Modifier.padding(top = 4.dp, bottom = 10.dp, start = 6.dp, end = 6.dp),
            verticalArrangement = Arrangement.Top,
        ) {
            KamelImage(
                resource = { asyncPainterResource(data = cast.profilePath) },
                contentDescription = cast.name,
                modifier = Modifier
                    .aspectRatio(16f/9f)
                    .align(Alignment.CenterHorizontally),
                contentScale = ContentScale.Crop,
                contentAlignment = Alignment.Center,
                onLoading = { _ ->
                    CircularProgressIndicator(
                        modifier = Modifier.align(Alignment.Center),
                        color = Color.Blue
                    )
                },
                onFailure = {
                    Image(
                        modifier = Modifier.fillMaxSize(),
                        contentScale = ContentScale.Crop,
                        painter = painterResource(Res.drawable.person),
                        contentDescription = "Fall back image"
                    )
                    it.printStackTrace()
                },
            )

            Spacer(modifier = Modifier.height(6.dp))

            Text(
                modifier = Modifier.fillMaxWidth(),
                textAlign = TextAlign.Start,
                text = cast.name,
                fontWeight = FontWeight.Bold,
                fontSize = 14.sp
            )

            Text(
                modifier = Modifier.fillMaxWidth(),
                textAlign = TextAlign.Start,
                text = cast.character,
                fontSize = 14.sp
            )
        }
    }
}

问题示例图

错误图片高度不一致示例


解决方案

问题核心是加载失败时的占位图没有严格遵循父容器的尺寸约束,以下是几种可行的解决方法:

方法1:给KamelImage设置固定宽度

通过固定图片容器的宽度,结合aspectRatio让高度自动计算,确保所有图片容器尺寸统一:

KamelImage(
    // 其他参数不变
    modifier = Modifier
        .width(100.dp) // 固定宽度,高度由16:9的比例自动推导
        .aspectRatio(16f/9f)
        .align(Alignment.CenterHorizontally),
    // 剩余代码不变
)

方法2:用Box统一包裹加载图和占位图

将KamelImage和错误占位图放在同一个Box容器中,利用层级关系确保占位图始终填充整个容器:

Box(
    modifier = Modifier
        .aspectRatio(16f/9f)
        .align(Alignment.CenterHorizontally)
) {
    KamelImage(
        resource = { asyncPainterResource(data = cast.profilePath) },
        contentDescription = cast.name,
        modifier = Modifier.fillMaxSize(),
        contentScale = ContentScale.Crop,
        contentAlignment = Alignment.Center,
        onLoading = { _ ->
            CircularProgressIndicator(
                modifier = Modifier.align(Alignment.Center),
                color = Color.Blue
            )
        },
        onFailure = { it.printStackTrace() }
    )
    // 始终存在的占位图,加载成功时会被KamelImage覆盖
    Image(
        modifier = Modifier.fillMaxSize(),
        contentScale = ContentScale.Crop,
        painter = painterResource(Res.drawable.person),
        contentDescription = "Fall back image",
        alpha = if (cast.profilePath.isNullOrEmpty()) 1f else 0f
    )
}

方法3:强制占位图填充父容器

在onFailure回调中,用Box包裹占位图并设置fillMaxSize,确保它严格遵循KamelImage的容器尺寸:

onFailure = {
    Box(modifier = Modifier.fillMaxSize()) {
        Image(
            modifier = Modifier.fillMaxSize(),
            contentScale = ContentScale.Crop,
            painter = painterResource(Res.drawable.person),
            contentDescription = "Fall back image"
        )
    }
    it.printStackTrace()
}

内容的提问来源于stack exchange,提问作者ant2009

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 12:09:53