这一节了解一下Compose中的AsyncImage的使用,AsyncImage是由 Coil库提供的一个用于异步加载图片的组件。它支持加载网络图片、本地图片资源,并提供了占位符、错误处理、过渡动画等功能,简单介绍如下:
API
1. model
含义:指定要加载的图片资源,可以是图片的URL(字符串类型)、本地资源ID(整数类型)或者其他支持的图片模型。
作用:告诉AsyncImage从哪里获取图片。
2. contentDescription
含义:图片的文字描述,主要用于无障碍访问,让屏幕阅读器等辅助设备能够向用户描述图片内容。
作用:增强应用的可访问性,方便视力障碍等用户了解图片信息。
3. placeholder
含义:图片加载过程中显示的占位符,通常是一个Painter对象,比如使用ColorPainter显示纯色占位符,或者使用BitmapPainter显示默认图片。
作用:在图片加载完成之前给用户提供视觉反馈,避免界面出现空白。
4. error
含义:图片加载失败时显示的图标,同样是一个Painter对象。
作用:当图片加载出现错误时,向用户展示友好的提示信息。
5. loading
含义:图片加载过程中显示的内容,是一个AsyncImagePainter.State.Loading状态下的Composable函数。
作用:可以自定义加载过程中的显示效果,比如添加加载动画。
6. contentScale
含义:指定图片的缩放方式,取值为 ContentScale 枚举类型,常见的有ContentScale.Fit(保持图片宽高比,将图片缩放至完全显示在容器内)、ContentScale.Crop(保持图片宽高比,裁剪图片以填充容器)等。
作用:控制图片在组件中的显示大小和比例。
栗子:
app下gradle添加依赖:
implementation("io.coil-kt:coil-compose:2.6.0")
//一般用法
@Composable
fun ImageTest() {
AsyncImage(
model = "https://gips2.baidu.com/it/u=2560577328,2450090727&fm=3042&app=3042&f=JPEG&wm=1,baiduai,0,0,13,9&wmo=0,0&w=512&h=512", // 图片 URL 或资源 ID
contentDescription = "Example Image", // 描述
modifier = Modifier.size(200.dp), // 图片大小
contentScale = ContentScale.Crop // 图片缩放模式
)
}
// 带占位图用法
val placeholder: Painter = painterResource(id = R.drawable.placeholder) // 占位图
val errorImage: Painter = painterResource(id = R.drawable.error) // 错误图
AsyncImage(
model = "https://gips2.baidu.com/it/u=2560577328,2450090727&fm=3042&app=3042&f=JPEG&wm=1,baiduai,0,0,13,9&wmo=0,0&w=512&h=512",
contentDescription = "Image with Placeholder",
modifier = Modifier.size(200.dp),
placeholder = placeholder,
error = errorImage
)
// 如果需要更复杂的图片加载配置(如缓存策略、请求头等),可以使用 ImageRequest:
val curContext = LocalContext.current
val request = remember {
ImageRequest.Builder(curContext)
.data("https://gips2.baidu.com/it/u=2560577328,2450090727&fm=3042&app=3042&f=JPEG&wm=1,baiduai,0,0,13,9&wmo=0,0&w=512&h=512")
.crossfade(true) // 启用淡入淡出动画
.build()
}
AsyncImage(
model = request,
contentDescription = "Custom Image Request",
modifier = Modifier.size(200.dp)
)
//这块这也可以配置缓存策略:
// .memoryCachePolicy(CachePolicy.ENABLED)
// .diskCachePolicy(CachePolicy.ENABLED)
//动态加载本地资源
val image: Painter = painterResource(id = R.drawable.android)
AsyncImage(
model = image, // 本地资源
contentDescription = "Local Image",
modifier = Modifier.size(200.dp)
)
注意这块会报异常:
Process: com.example.composenavigationdemo, PID: 4787
java.lang.IllegalArgumentException: Unsupported type: Painter. If you wish to display this Painter, use androidx.compose.foundation.Image.
at coil.compose.AsyncImagePainterKt.unsupportedData(AsyncImagePainter.kt:459)
at coil.compose.AsyncImagePainterKt.unsupportedData$default(AsyncImagePainter.kt:456)
at coil.compose.AsyncImagePainterKt.validateRequest(AsyncImagePainter.kt:451)
at coil.compose.AsyncImagePainterKt.rememberAsyncImagePainter-GSdzBsE(AsyncImagePainter.kt:202)
at coil.compose.AsyncImagePainterKt.rememberAsyncImagePainter-0YpotYA(AsyncImagePainter.kt:167)
at coil.compose.AsyncImageKt.AsyncImage-76YX9Dk(AsyncImage.kt:220)
at coil.compose.AsyncImageKt.AsyncImage-QgsmV_s(AsyncImage.kt:158)
at coil.compose.SingletonAsyncImageKt.AsyncImage-gl8XCv8(SingletonAsyncImage.kt:162)
at com.example.composenavigationdemo.test.ImageTestKt.ImageTest(ImageTest.kt:58)
调整如下就可以解决:
model = R.drawable.android
监听图片加载状态
AsyncImage(
model = "https://gips2.baidu.com/it/u=2560577328,2450090727&fm=3042&app=3042&f=JPEG&wm=1,baiduai,0,0,13,9&wmo=0,0&w=512&h=512",
contentDescription = "测试图片",
onState = { state ->
when (state) {
is AsyncImagePainter.State.Loading -> {
// 图片正在加载
}
is AsyncImagePainter.State.Success -> {
// 图片加载成功
}
is AsyncImagePainter.State.Error -> {
// 图片加载失败
}
else -> {
}
}
},
modifier = Modifier.size(200.dp)
)
注意:
1 网络权限: 如果加载网络图片,需要在 AndroidManifest.xml 中添加网络权限。
2 图片缓存: Coil 会自动处理图片的内存和磁盘缓存,无需额外配置。
3 性能优化: 在列表中加载大量图片时,建议使用 LazyColumn 或 SubcomposeAsyncImage 来优化性能。