Compose之图片加载显示

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>

这样也更合理,安全范围可控。

相关推荐
fundroid17 小时前
掌握 Compose 性能优化三步法
android·android jetpack
ljt27249606615 天前
Compose笔记(五十一)--rememberTextMeasurer
android·笔记·android jetpack
wxson72829 天前
【用androidx.camera拍摄景深合成照片】
kotlin·android jetpack·androidx
天花板之恋10 天前
Compose Navigation总结
android jetpack
alexhilton10 天前
灵活、现代的Android应用架构:完整分步指南
android·kotlin·android jetpack
4z3312 天前
Jetpack Compose重组原理(一):快照系统如何精准追踪状态变化
前端·android jetpack
木易 士心12 天前
Android Jetpack Compose 从入门到精通
android·android jetpack
alexhilton12 天前
如何构建Android应用:深入探讨原则而非规则
android·kotlin·android jetpack
雨白12 天前
使用 Jetpack Compose 构建一个整洁架构笔记应用
android·android jetpack·mvvm
Lei活在当下18 天前
【业务场景架构实战】5. 使用 Flow 模式传递状态过程中的思考点
android·架构·android jetpack