如何学会使用Coil

3,160 阅读7分钟

1、前言

月末了,再写一篇文章和各位分享下,想到啥就写啥了,基本所有示例都是脑子一抽就写出来了。如果写的不好,或者有错误之处,恳请在评论、私信、邮箱指出,万分感谢🙏。

今天来了解下Coil库,Coil是一个专为Android应用程序设计的轻量级图像加载库,具有以下特点:

  1. 简洁易用:Coil提供简单直观的API和易于理解的接口,使得图像加载变得简单而不费力。
  2. 高效性能:Coil使用现代的图像加载技术和优化策略,以实现高效的图像加载和显示,并提供平滑的滚动体验。
  3. 灵活可定制:Coil允许开发人员通过自定义组件、插件和转换器来扩展其功能,以满足各种不同的图像加载需求。
  4. 自动化:Coil支持自动化的磁盘和内存缓存管理,以减少对开发人员的额外负担。
  5. 资源优化:Coil能够根据目标设备的屏幕密度自动选择适当的图像资源,以提供最佳的显示效果。

先看看怎么使用吧

2、依赖

 dependencies {
     implementation("io.coil-kt:coil:2.4.0")
 }

3、使用

 class MainActivity : AppCompatActivity() {
     private lateinit var binding: ActivityMainBinding
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         binding = ActivityMainBinding.inflate(layoutInflater)
         setContentView(binding.root)
         binding.run {
             iv1.load("https://zyc-essay.oss-cn-beijing.aliyuncs.com/share/58299381-0aea-46c9-bbfb-28921d8e7db6.jpeg")
         }
     }
 }

Screenshot_2023-06-26-10-41-08-644_com.nofish.ima

没了............

开玩笑啦,怎么可能没了嘛。

可以看到得益于Kotlin的语法糖,加载图片不能说简单吧,只能说几乎弱智了。不过load是一个多参数的方法的。我们来看看。image-20230626103805963

可以看到有两个参数是带有默认值的,ImageLoaderImageRequest

4、ImageRequest

ImageRequest是用于加载和管理图像的关键概念。ImageRequest对象封装了加载图像所需的所有信息,它为 ImageLoader 提供加载图像所需的所有信息。

1)创建ImageRequest:

你可以使用ImageRequest.Builder()来创建一个ImageRequest对象。在构建器中,你可以指定图像的URL、可选的加载参数和选项。例如:

 val request = ImageRequest.Builder(this@MainActivity)
     .data("https://zyc-essay.oss-cn-beijing.aliyuncs.com/share/b2fdc814-969b-437e-8af9-6c1efcaec5ba.jpeg")
     .size(400, 300) // 设置图像的目标尺寸
     .placeholder(R.mipmap.placeholder) // 设置占位图
     .error(R.mipmap.error) // 设置加载错误时显示的图像
     .build()

2)加载和显示图像

如果创建了ImageRequest对象使用起来也是一致的

 iv2.load(request)

3)图像变换和处理

  • 指定图像的URL或任何其他数据源,如文件路径、资源ID等。

     fun data("https://example.com/image.jpg")
    
  1. 指定图像的目标宽度和高度

     fun size(300, 300)
    
  • 指定图像的缩放类型,如填充(Scale.FILL)、适应(Scale.FIT)。

     fun scale(Scale.FILL)
    
  • 指定图像的网络缓存策略,如启用缓存(CachePolicy.ENABLED)、禁用缓存(CachePolicy.DISABLED)等。

     fun networkCachePolicy(CachePolicy.ENABLED)
    
  • 指定在加载图像时发生错误时显示的占位图。

     fun error(R.drawable.error)
    
  • 指定在图像加载过程中显示的占位图。

     fun placeholder(R.drawable.placeholder)
    
  • 启用图像加载时的淡入淡出效果,实现平滑的过渡效果。

     fun crossfade(true)
    
  • 添加图像的变换操作,如圆形裁剪(CircleCropTransformation)、高斯模糊(BlurTransformation)等。

     fun transformations(CircleCropTransformation())
    
  • 指定图像的内存缓存策略,如启用缓存(CachePolicy.ENABLED)、禁用缓存(CachePolicy.DISABLED)等。

     fun memoryCachePolicy(CachePolicy.ENABLED)
    
  • 指定图像的磁盘缓存策略,如启用缓存(CachePolicy.ENABLED)、禁用缓存(CachePolicy.DISABLED)等。

     fun diskCachePolicy(CachePolicy.ENABLED)
    
  • 添加图像加载的监听器,可在加载开始、成功或失败时执行相应的操作。

     fun listener(
         onStart = {/* 加载开始时执行的操作 */ },
         onCancel = {/* 加载取消时执行的操作 */ },
         onError = { request, result ->/* 加载失败时执行的操作 */ },
         onSuccess = { request, result ->/* 加载成功时执行的操作 */ })
    
  • 设置是否启用预乘透明度

     fun premultipliedAlpha(enable: Boolean)
    
  • 置网络请求的头部信息

     fun addHeader(name: String, value: String)
    
  • 设置当数据源为空时的备用占位符

     fun fallback(drawable: Drawable?)
    
  • 设置是否允许使用 RGB565 格式

     fun allowRgb565(enable: Boolean)
    
  • 允许将结果转换为位图

     fun allowConversionToBitmap(enable: Boolean)
    
  • 设置数据解码的工厂

     fun decoderFactory(factory: Decoder.Factory)
    
  • 设置图像加载的精度

     fun precision(precision: Precision)
    
  • 设置缩略图请求

     fun thumbnail(thumbnail: RequestBuilder<Drawable>?)
    
  • 设置图像加载的过渡效果

     fun transition(transition: Transition)
    

等等,还有很多啦,就看看文档吧去

大概是下面这么用的,如下

 val request2 = ImageRequest.Builder(this@MainActivity)
             .data("https://zyc-essay.oss-cn-beijing.aliyuncs.com/share/58299381-0aea-46c9-bbfb-28921d8e7db6.jpeg")
             .size(400, 300) // 设置图像的目标尺寸
             .scale(Scale.FIT)//Scale.FILL / Scale.FIT
             .networkCachePolicy(CachePolicy.ENABLED).error(R.mipmap.error) // 设置加载错误时显示的图像
             .placeholder(R.mipmap.placeholder) // 设置占位图
             .crossfade(true).transformations(CircleCropTransformation())
             .memoryCachePolicy(CachePolicy.ENABLED).diskCachePolicy(CachePolicy.ENABLED)
             .listener(
                 onStart = {/* 加载开始时执行的操作 */ },
                 onCancel = {/* 加载取消时执行的操作 */ },
                 onError = { request, result ->/* 加载失败时执行的操作 */ },
                 onSuccess = { request, result ->/* 加载成功时执行的操作 */ }
             ).build()

4)取消图像加载

如果需要取消正在进行的图像加载操作,你可以使用返回的Disposable对象

image-20230626114253960

image-20230626114401195

5、ImageLoader

说完了ImageRequest,我们接着来说ImageLoader

从名字来看我们就能猜测负责管理图像加载过程,官方是这么说的

A service class that loads images by executing ImageRequests. Image loaders handle caching, data fetching, image decoding, request management, memory management, and more. Image loaders are designed to be shareable and work best when you create a single instance and share it throughout your app.

一个通过执行ImageRequests加载图像的服务类。图像加载程序处理缓存、数据获取、图像解码、请求管理、内存管理等。 图片加载器被设计成可共享的,当你创建一个实例并在整个应用程序中共享它时,效果最好。

按照官方说的创建一个共享的实例ImageLoader,我们可以在Application中创建

 class MyApp : Application(), ImageLoaderFactory {
     override fun newImageLoader(): ImageLoader {
         return ImageLoader.Builder(applicationContext)
             .crossfade(true)
             .okHttpClient {
                 OkHttpClient.Builder()
                     .cache(CoilUtils.createDefaultCache(applicationContext))
                     .build()
             }
             .build()
     }
 }

共享一个是因为每个 ImageLoader 都有自己的内存缓存、磁盘缓存和 OkHttpClient。所以最好用一个啦。

从上面的代码你可以看到ImageLoader是使用Builder构建出来的,让我们来看看还有什么属性可以操作吧

 class Builder {
    private val applicationContext: Context
    private var defaults: DefaultRequestOptions
    private var memoryCache: Lazy<MemoryCache?>?
    private var diskCache: Lazy<DiskCache?>?
    private var callFactory: Lazy<Call.Factory>?
    private var eventListenerFactory: EventListener.Factory?
    private var componentRegistry: ComponentRegistry?
    private var options: ImageLoaderOptions
    private var logger: Logger?
 }

applicationContext就不说了看别的

每一个值都有相关的方法,东西不多,我直接挪列出来吧~

  • okHttpClient(okHttpClient: OkHttpClient)okHttpClient(initializer: () -> OkHttpClient):设置用于网络请求的OkHttpClient实例。你可以直接传入一个已经创建好的OkHttpClient实例,或者使用懒加载的方式在后台线程上创建OkHttpClient实例。
  • callFactory(callFactory: Call.Factory)callFactory(initializer: () -> Call.Factory):设置用于网络请求的Call.Factory。你可以直接传入一个已经创建好的Call.Factory实例,或者使用懒加载的方式在后台线程上创建Call.Factory实例。
  • components(builder: ComponentRegistry.Builder.() -> Unit)components(components: ComponentRegistry):设置用于构建和配置ComponentRegistry
  • memoryCache(memoryCache: MemoryCache?)memoryCache(initializer: () -> MemoryCache?):设置内存缓存MemoryCache。你可以直接传入一个MemoryCache实例,或者使用懒加载的方式在后台线程上创建MemoryCache实例。
  • diskCache(diskCache: DiskCache?)diskCache(initializer: () -> DiskCache?):设置磁盘缓存DiskCache。你可以直接传入一个DiskCache实例,或者使用懒加载的方式在后台线程上创建DiskCache实例。
  • allowHardware(enable: Boolean):是否允许使用Bitmap.Config.HARDWARE进行图像加载,默认为true
  • allowRgb565(enable: Boolean):是否在图像没有透明度的情况下自动使用Bitmap.Config.RGB_565,默认为false
  • addLastModifiedToFileCacheKey(enable: Boolean):是否将FilelastModified添加到内存缓存键中,默认为true
  • networkObserverEnabled(enable: Boolean):是否启用离线时自动禁用网络请求,默认为true
  • respectCacheHeaders(enable: Boolean):是否启用网络缓存头的支持,默认为true
  • bitmapFactoryMaxParallelism(maxParallelism: Int):设置BitmapFactory并行解码操作的最大数量,默认为4。
  • bitmapFactoryExifOrientationPolicy(policy: ExifOrientationPolicy):设置处理由BitmapFactoryDecoder解码的图像的EXIF方向标志的策略,默认为ExifOrientationPolicy.RESPECT_PERFORMANCE
  • eventListener(listener: EventListener)eventListenerFactory(factory: EventListener.Factory):设置用于接收请求的事件回调的EventListener
  • crossfade(enable: Boolean)crossfade(durationMillis: Int):启用或设置交叉淡入淡出动画的持续时间。
  • transitionFactory(factory: Transition.Factory):设置默认的过渡动画工厂。
  • precision(precision: Precision):设置请求的默认精确度。
  • bitmapConfig(bitmapConfig: Bitmap.Config):设置首选的Bitmap.Config
  • dispatcher(dispatcher: CoroutineDispatcher):设置用于执行图像加载任务的调度程序,默认为Dispatchers.Main
  • transformations(vararg transformations: Transformation):设置要应用于加载的图像的转换。
  • allowRgb565OnSlowDevices(enable: Boolean):是否在慢速设备上自动使用Bitmap.Config.RGB_565,默认为true

6、下个篇章

因为篇幅原因,我们先到这,主要还是介绍属性啦,还有更多用法,下篇马上~咕咕咕。

如果您有任何疑问、对文章写的不满意、发现错误或者有更好的方法,欢迎在评论、私信或邮件中提出,非常感谢您的支持。🙏

代码都在这里啦,可能有所出入,大差不差啦