1.加载本地图片
1.1规定图片显示大小:
kotlin
Image(painterResource(R.drawable.ic_baseline_home_24), "home", Modifier.size(50.dp,50.dp))
1.2根据内容自适应显示:
kotlin
Image(painterResource(R.drawable.ic_baseline_home_24), "home", Modifier.wrapContentSize())
1.3增加图片缩放方式:
kotlin
Image(painterResource(R.drawable.ic_baseline_home_24),
"home",
Modifier.size(50.dp,50.dp),
contentScale = ContentScale.Crop)
图片缩放的规则和传统View的规则是一样的:
ContentScale.Fit
(默认值,如果未指定),保持图像的原始宽高比,同时缩放图像,使其完全适应 (fit) 目标边界。这意味着图像的某一边(宽或高)将与边界匹配,而另一边可能会小于边界,从而在图像周围留下空白区域。
ContentScale.Crop,保持图像的原始宽高比,同时缩放图像,使其完全填满 (crop) 目标边界。这通常意味着图像的一部分会被裁剪掉,以便图像的两个维度都能至少覆盖边界。
ContentScale.FillBounds,独立地缩放图像的宽度和高度,使其完全填满目标边界,不保持原始宽高比。
ContentScale.FillWidth,保持图像的原始宽高比,缩放图像使其宽度与目标边界的宽度匹配。图像的高度将根据原始宽高比进行缩放。
ContentScale.FillHeight,保持图像的原始宽高比,缩放图像使其高度与目标边界的高度匹配。图像的宽度将根据原始宽高比进行缩放。
ContentScale.Inside,保持图像的原始宽高比。如果图像本身小于或等于目标边界,则不进行缩放,并将其居中放置。如果图像大于目标边界,则行为类似于 ContentScale.Fit,即缩放以适应边界内部。
ContentScale.None,不进行任何缩放。 图像将以其原始尺寸绘制。如果图像大于目标边界,它将被裁剪。如果小于边界,则会在其周围留下空白。通常,图像会从边界的左上角开始绘制(取决于对齐方式)。
2.使用图片加载框架coil
2.1配置依赖
--libs.versions.toml
kotlin
[versions]
coil = "3.3.0"
[libraries]
coil = {group = "io.coil-kt.coil3", name = "coil-compose", version.ref = "coil"}
okhttp = {group = "io.coil-kt.coil3", name = "coil-network-okhttp", version.ref = "coil"}
--build.gradle.kts(app)
kotlin
dependencies {
implementation(libs.coil)
implementation(libs.okhttp)
}
我使用了最新的coil版本3.3.0,也可以进coil官网查看coil-kt.github.io/coil/compos...。 这里非常重要的一点,就是要记得引入okhttp。coil这一点跟glide一样,它只是负责生成和管理请求,以及图片缓存和其他上层逻辑处理,底层的网络请求还是需要依赖其他http请求库。 如果不配置底层okhttp依赖,会提示:
kotlin
2025-09-12 16:48:52.022 18201-18201 RealImageLoader com.yys.xilixili E java.lang.IllegalStateException: Unable to create a fetcher that supports: https://images.unsplash.com/photo-1604156788856-2ce5f2171cce?fm=jpg&q=60&w=1920
2.2最简单的使用方式:
kotlin
val url_img2 = "https://img2.baidu.com/it/u=29207272,3998824514&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=892"
Image(rememberAsyncImagePainter(url_img2), "钢铁暴龙兽") //加载成功
coil通过rememberAsyncImagePainter去异步获取一个Painter,然后使用compose标准的API显示图片。
2.3多配置使用方式:
kotlin
val url_img3 = "https://images.unsplash.com/photo-1604156788856-2ce5f2171cce?fm=jpg&q=60&w=1920"
val imageLoader = ImageLoader.Builder(applicationContext)
.logger(DebugLogger()) //通过调整log等级来查看coil内部的日志
.memoryCache {
MemoryCache.Builder()
.maxSizePercent(this,0.25)
.build()
} //设置内存缓存大小为应用总内存的25%
.diskCache {
DiskCache
.Builder()
.maxSizeBytes(1024 * 1024 * 50)
.build()
} // 设置磁盘存储大小为50M
.build()
AsyncImage(
model = url_img2,
"钢铁暴龙兽",
modifier = Modifier.size(200.dp),
contentScale = ContentScale.Crop, //图片缩放方式
error = painterResource(R.drawable.error), //请求失败展示图片
placeholder = painterResource(R.drawable.load_img), //请求前的占位图片
imageLoader = imageLoader) //设置自定义的ImageLoader
coil是默认的日志级别比较高,错误日志不会打印,这对调试不友好,好在coil可以自定义Logger。
3.踩坑点:
kotlin
val url_img1 = "http://img2.baidu.com/it/u=29207272,3998824514&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=892"
Image(rememberAsyncImagePainter(url_img1), "钢铁暴龙兽") //有问题,加载失败
提示如下错误:
kotlin
Failed - http://img2.baidu.com/it/u=29207272,3998824514&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=892
2025-09-13 09:34:40.431 20870-20870 RealImageLoader com.yys.xilixili E java.net.UnknownServiceException: CLEARTEXT communication to img2.baidu.com not permitted by network security policy
这是由于Android 9 以上,默认情况下禁止应用使用未加密的 HTTP 连接。解决这样的问题有两种方式: 1. 在 AndroidManifest.xml 中设置 android:usesCleartextTraffic="true",这是允许所有明文网络请求,但这不太推荐。
2. 对特定的域名做明文请求许可 首先建立一个XML文件:
xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">img2.baidu.com</domain>
<!-- 只允许这个域名使用 HTTP -->
</domain-config>
<!-- 你可以为其他域名添加更多的 <domain-config> -->
</network-security-config>
然后在 AndroidManifest.xml 文件的 <application>
标签中引用这个配置文件:
xml
<application
android:networkSecurityConfig="@xml/network_security_config"
...>
...
</application>
这样也更合理,安全范围可控。