一、概念
相比 Glide、Picasso 而言,Coil 更专注于 Compose 且它的代码使用 Kotlin。
二、添加依赖
val coilVersion = "3.3.0"
implementation("io.coil-kt.coil3:coil-compose:$coilVersion")
//可选,如果没有集成过 Retrofit 或 OKHttp 的话
implementation("io.coil-kt.coil3:coil-network-okhttp:$coilVersion")
//可选,支持GIF
implementation("io.coil-kt.coil3:coil-gif:$coilVersion")
//可选,支持SVG
implementation("io.coil-kt.coil3:coil-svg:$coilVersion")
三、简单使用
根据加载的状态,AsyncImage() 只能设置不同的图,SubcomposeAsyncImage() 可以设置不同界面。
| 单界面 | @Composable |
| @Composable @NonRestartableComposable fun AsyncImage( model: Any?, contentDescription: String?, modifier: Modifier = Modifier, transform: (State) -> State = DefaultTransform, onState: ((State) -> Unit)? = null, //状态被合并需要手动判断 alignment: Alignment = Alignment.Center, contentScale: ContentScale = ContentScale.Fit, alpha: Float = DefaultAlpha, colorFilter: ColorFilter? = null, filterQuality: FilterQuality = DefaultFilterQuality, clipToBounds: Boolean = true, ) | |
| 多界面 | @Composable //加载界面 //成功界面 //失败界面 |
AsyncImage(
model = "https://example.com/image.jpg", //网络资源
// model = R.drawable.bkg_naruto, //本地资源(没必要,用系统自带的Image)
//需要手动判断状态的重载
onState = { state ->
when(state) {
AsyncImagePainter.State.Empty -> TODO()
is AsyncImagePainter.State.Error -> TODO()
is AsyncImagePainter.State.Loading -> TODO()
is AsyncImagePainter.State.Success -> TODO()
}
}
)
四、全局配置 ImageLoader
非必须,不自定义会使用默认的。
4.1 初始化方式(选一个)
4.1.1 通过 Application 实现(推荐)
class MyApplication : Application(), SingletonImageLoader.Factory {
override fun newImageLoader(context: PlatformContext): ImageLoader {
return ImageLoader.Builder(context)
.build()
}
}
4.1.2 通过 Application#onCreate() 调用
确保不会覆盖已创建的现有图像加载器。如果是单 Activity 也可以在 Activity#onCreate() 中调用。
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
SingletonImageLoader.setSafe { context ->
ImageLoader.Builder(context)
.build()
}
}
}
4.1.3 通过 Compose 根入口调用
适合 Compose Multiplatform。
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
setSingletonImageLoaderFactory { context ->
ImageLoader.Builder(context)
.build()
}
Screen()
}
}
}
4.1.4 通过 StartUp 配置
class CoilInitializer : Initializer<SingletonImageLoader> {
override fun create(context: Context): SingletonImageLoader {
SingletonImageLoader.setSafe { context ->
ImageLoader.Builder(context)
.build()
}
return SingletonImageLoader
}
override fun dependencies(): List<Class<out Initializer<*>?>?> {
return mutableListOf()
}
}
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge"
>
<meta-data
android:name="com.momentum.ui.core.startup.CoilInitializer"
android:value="androidx.startup"
/>
</provider>
4.2 功能配置
ImageLoader.Builder(context)
//淡入淡出
.crossfade(true) //传入Int多少毫秒,或true为200
//添加日志(会降低性能,且不要用于生产环境!)
.logger(DebugLogger())
//内存缓存
.memoryCache {
MemoryCache.Builder()
.maxSizePercent(context, 0.25) //此APP可用内存的百分比
.build()
}
//磁盘缓存
.diskCache {
DiskCache.Builder()
.directory(context.cacheDir.resolve("coil_cache"))
.maxSizePercent(0.2) //设备可用磁盘空间的百分比
.build()
}
//更多特性支持
.components {
//支持SVG
add(SvgDecoder.Factory())
//支持GIF
if (SDK_INT >= 28) {
add(AnimatedImageDecoder.Factory())
} else {
add(GifDecoder.Factory())
}
}
.build()
//清除缓存
SingletonImageLoader.get(context).memoryCache?.clear()
SingletonImageLoader.get(context).diskCache?.clear()
五、请求配置 ImageRequest
单独对可组合项设置,会覆盖全局设置。
AsyncImage(
model = ImageRequest.Builder(LocalContext.current)
.data("https://example.com/image.jpg")
.crossfade(true)
.size(30) //限制图片的像素大小
.build()
)
六、返回 Painter 而不使用可组合项
当不方便使用 AsyncImage() 或 SubcomposeAsyncImage() 可组合项时,返回一个 Painter 可用于自带组件 Image()。
| @Composable @NonRestartableComposable fun rememberAsyncImagePainter( model: Any?, imageLoader: ImageLoader, placeholder: Painter? = null, error: Painter? = null, fallback: Painter? = error, onLoading: ((State.Loading) -> Unit)? = null, onSuccess: ((State.Success) -> Unit)? = null, onError: ((State.Error) -> Unit)? = null, contentScale: ContentScale = ContentScale.Fit, filterQuality: FilterQuality = DefaultFilterQuality, ) |
| @Composable @NonRestartableComposable fun rememberAsyncImagePainter( model: Any?, transform: (State) -> State = DefaultTransform, onState: ((State) -> Unit)? = null, //状态合并版本 contentScale: ContentScale = ContentScale.Fit, filterQuality: FilterQuality = DefaultFilterQuality, ) |
val painter = rememberAsyncImagePainter(
model = ""
)
//设置给自带控件
Image(
painter = painter,
contentDescription = ""
)
//收集状态加载不同界面
val state by painter.state.collectAsState()
when(state) {
AsyncImagePainter.State.Empty -> TODO()
is AsyncImagePainter.State.Error -> TODO()
is AsyncImagePainter.State.Loading -> TODO()
is AsyncImagePainter.State.Success -> TODO()
}
七、网图预览处理
由于预览环境禁用了网络访问,因此网络 URL 的请求将始终失败。在 Android Studio 预览中的行为由 LocalAsyncImagePreviewHandler 控制。
val previewHandler = AsyncImagePreviewHandler {
ColorImage(Color.Red.toArgb())
}
CompositionLocalProvider(LocalAsyncImagePreviewHandler provides previewHandler) {
AsyncImage(
model = "https://example.com/image.jpg",
contentDescription = null,
)
}

1877

被折叠的 条评论
为什么被折叠?



