使用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
相关产品推荐
相关产品推荐

