文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android 图片加载库之Coil的详解与使用

2023-10-02 05:11

关注

一、介绍

        在Android,资源的呈现主要有三大形式:文字、图片、视频。图片有分为本地资源和网络资源。

网络资源需要通过下载然后绑定到ImageView中。

        在前期我们使用的图片加载框架如:picasso、gliade、imageload。这些框架都可以满足我们正常的图片加载到显示,且这些框架都是通过Java语言开发出来。接下来,我将介绍一款以kotlin语言开发的框架Coil。

Coil的介绍

一、介绍

 是一个 Android 图片加载库,通过Kotlin协程的方式加载图片

优势

2、集成

io.coil-kt:coil-base : 基础组件,提供了基本的图片请求、图片解码、图片缓存等
io.coil-kt:coil : 默认组件,依赖于io.coil-kt:coil-base,提供了 Coil 类的单例对象以及 ImageViews 相关的扩展函数
io.coil-kt:coil-gif : 用于支持解码 GIFs
io.coil-kt:coil-svg : 用于支持解码 SVG
io.coil-kt:coil-video : 包含两个 fetchers 用于支持读取和解码 任何 Android 的支持的视频格式 的视频帧

//依赖库

    implementation("io.coil-kt:coil:1.2.2")//    //选择添加    implementation("io.coil-kt:coil-gif:1.2.2")//支持GIF    implementation("io.coil-kt:coil-svg:1.2.2")//支持SVG    implementation("io.coil-kt:coil-video:1.2.2")//支持Video

3、使用

由于在kotlin支持方法的扩展,所以ImageViews已支持提供了load方法,默认只需要传入图片地址即可。

@JvmSyntheticinline fun ImageView.load(    uri: String?,    imageLoader: ImageLoader = context.imageLoader,    builder: ImageRequest.Builder.() -> Unit = {}): Disposable = loadAny(uri, imageLoader, builder)@JvmSyntheticinline fun ImageView.load(    url: HttpUrl?,    imageLoader: ImageLoader = context.imageLoader,    builder: ImageRequest.Builder.() -> Unit = {}): Disposable = loadAny(url, imageLoader, builder)@JvmSyntheticinline fun ImageView.load(    uri: Uri?,    imageLoader: ImageLoader = context.imageLoader,    builder: ImageRequest.Builder.() -> Unit = {}): Disposable = loadAny(uri, imageLoader, builder)@JvmSyntheticinline fun ImageView.load(    file: File?,    imageLoader: ImageLoader = context.imageLoader,    builder: ImageRequest.Builder.() -> Unit = {}): Disposable = loadAny(file, imageLoader, builder)@JvmSyntheticinline fun ImageView.load(    @DrawableRes drawableResId: Int,    imageLoader: ImageLoader = context.imageLoader,    builder: ImageRequest.Builder.() -> Unit = {}): Disposable = loadAny(drawableResId, imageLoader, builder)@JvmSyntheticinline fun ImageView.load(    drawable: Drawable?,    imageLoader: ImageLoader = context.imageLoader,    builder: ImageRequest.Builder.() -> Unit = {}): Disposable = loadAny(drawable, imageLoader, builder)@JvmSyntheticinline fun ImageView.load(    bitmap: Bitmap?,    imageLoader: ImageLoader = context.imageLoader,    builder: ImageRequest.Builder.() -> Unit = {}): Disposable = loadAny(bitmap, imageLoader, builder)

load支持的请求类型

uri: String:图片地址
url: HttpUrl:封装好的请求url
uri: Uri:Uri的资源封装
file: File:文件类型
drawableResId: Int:资源id
drawable: Drawable:drawable对象
bitmap: Bitmap:bitmap对象

加载load,返回一个Disposable,Disposable是IPC的接口,如下

interface Disposable {        val isDisposed: Boolean        fun dispose()        @ExperimentalCoilApi    suspend fun await()}

通过Disposable可以判断是否完成,主动调用以及等待。

扩展:

Coil不仅提供了默认的加载,还可以扩展其他。

inline fun ImageView.load(    uri: String?,    imageLoader: ImageLoader = context.imageLoader,    builder: ImageRequest.Builder.() -> Unit = {}): Disposable = loadAny(uri, imageLoader, builder)

通过源码可以看到,requestbuild是支持扩展的。默认后面是{},可以在{}体中调用build中方法。

         bind.image.load(url){                //build 扩展体                crossfade(true) //渐进渐出                placeholder(R.mipmap.ic_launcher) //加载中占位图                error(R.mipmap.ic_launcher)  //加载失败占位图                allowHardware(true)//硬件加速                allowRgb565(true)//支持565格式                lifecycle(lifecycle)//生命周期关联                var default= DefaultRequestOptions()                defaults(default)            }

包括网络缓存等,我们可以自己根据业务配置。如果你需要可以自定义一个ImageRequest.Build

ImageView高阶变换

Transformation(图片变换)

  • BlurTransformation() : 高斯模糊变换
  • CircleCropTransformation() : 圆形裁剪变换
  • GrayscaleTransformation() : 灰度变换
  • RoundedCornersTransformation() : 圆角变换

 

高阶图片变形通过transformations()来完成,支持多样式。

 

BlurTransformation() : 高斯模糊变换

class BlurTransformation @JvmOverloads constructor(    private val context: Context,    private val radius: Float = DEFAULT_RADIUS,    private val sampling: Float = DEFAULT_SAMPLING)
 init {        require(radius in 0.0..25.0) { "radius must be in [0, 25]." }        require(sampling > 0) { "sampling must be > 0." }    }

radius:模糊半径范围在0到25之间,数值越大,模糊越深

sampling:采样率必须大于,这个值是进行缩放图片大小的,(0,1),图片是越来越大,[1,++oo),图片是越来越小

 

GrayscaleTransformation() : 灰度变换

这个主要把彩色的图片置灰,常见特殊忌日,可以设置,利用了ColorMatrixColorFilter对颜色进行过滤。

RoundedCornersTransformation:圆角角度设置

class RoundedCornersTransformation(    @Px private val topLeft: Float = 0f,    @Px private val topRight: Float = 0f,    @Px private val bottomLeft: Float = 0f,    @Px private val bottomRight: Float = 0f) 

A=topleft ,B=topright,C=bottomLeft,D=bottomRight。

如果只传一个参数,默认就是四个角的角度,角度默认值是0,任何角的坐标都是(x,y),所以你设置角度无法只设置一个叫的一半。

如果想了解view的角度自定义,可以查看:

Android ImageView 四个角自定义角度,以及角度的变换_addroundrect_蜗牛、Z的博客-CSDN博客

 

参数扩展

有人用习惯了Glide或者imageload,会发现,可以通过配置来管理加载中,加载失败等标识,Coil同样也支持,只是通过build提供的方法来完成。

inline fun ImageView.load(    uri: String?,    imageLoader: ImageLoader = context.imageLoader,    builder: ImageRequest.Builder.() -> Unit = {}): Disposable = loadAny(uri, imageLoader, builder)
        bind.load.setOnClickListener {            bind.image.load("https://img-blog.csdnimg.cn/3a4114c916904ecbadb7a71b77294eef.gif"){                crossfade(true) //渐进渐出                placeholder(R.mipmap.ic_launcher) //加载中占位图                error(R.mipmap.ic_launcher)  //加载失败占位图                allowHardware(true)//硬件加速//                transformations(BlurTransformation(context,25f,2f))                //圆角                transformations(RoundedCornersTransformation(90f,0f,0f,0f))            }        }

有人会有疑问:

builder: ImageRequest.Builder.() -> Unit = {}

这个写法,是返回builder类,通过指向类的内部方法来完成,最后返回build。

小试牛刀:

class Build {      var msgs: String? = ""    fun setMsg(msg: String) = apply {        this.msgs = msg    }}


 

class TestBody(var build: Build.() -> Unit = {}) {    fun log() {        var mBuild = Build()        mBuild.apply(build)        mBuild.msgs?.let { MyLog.log(it) }    }}fun main() {    var test = TestBody({        setMsg("hello")    })    test.log()}

build是一个block object的,我们可以通过Build对象apply方法copy这个对象。

GIF动态图片加载

        Coil库不仅支持静态图片,也支持动态图片。只是动态和静态的解析对象不同ComponentRegistry在注册的时候,已提供了各种拦截与支持。

依赖库的引入:

implementation("io.coil-kt:coil-gif:1.2.2")//支持GIF

 

decoder目前提供两种方式:

api<28

class GifDecoder : Decoder

api>=28

@RequiresApi(28)class ImageDecoderDecoder : Decoder

ImageLoad初始化:

注意GIFDecoder类的顶部注释:

NOTE: Prefer using ImageDecoderDecoder on API 28 and above.

        //创建 gif ImageLoader 实例        val imageLoader = ImageLoader.Builder(applicationContext)            .componentRegistry {                if (SDK_INT >= 28) {                    add(ImageDecoderDecoder(applicationContext))                } else {                    add(GifDecoder())                }            }.build()        //设置全局唯一实例        Coil.setImageLoader(imageLoader)

这样我们就完成了Gif的ImageLoader的设置

如何监听图片加载:

ImageRequest提供了fun listener(listener: Listener?) 方法。
bind.image.load("https://img-blog.csdnimg.cn/3a4114c916904ecbadb7a71b77294eef.gif") {                  listener(object : ImageRequest.Listener {                    override fun onCancel(request: ImageRequest) {                        super.onCancel(request)                    }                    override fun onSuccess(request: ImageRequest, metadata: ImageResult.Metadata) {                        super.onSuccess(request, metadata)                    }                    override fun onError(request: ImageRequest, throwable: Throwable) {                        super.onError(request, throwable)                    }                    override fun onStart(request: ImageRequest) {                        super.onStart(request)                    }                })            }

关于配置

上面都是通过方法设置配置参数,如何设置全局配置?需要我们自己去设置一个全局的 ImageLoader.Builder

  val okHttpClient = OkHttpClient.Builder()            .cache(CoilUtils.createDefaultCache(this))            .build()        val imageLoader = ImageLoader.Builder(this)            .availableMemoryPercentage(0.5f)            .diskCachePolicy(CachePolicy.ENABLED)  //磁盘缓策略 ENABLED、READ_ONLY、WRITE_ONLY、DISABLED            .crossfade(true) //淡入淡出            .okHttpClient {  //设置okhttpClient实例                okHttpClient            }.build()        Coil.setImageLoader(imageLoader)

api介绍:

1.availableMemoryPercentage:

设置用于此 ImageLoader 的内存缓存和位图池的可用内存百分比,如果设置了百分百,那么cache将会失效

//源码   fun availableMemoryPercentage(@FloatRange(from = 0.0, to = 1.0) percent: Double) = apply {            require(percent in 0.0..1.0) { "Percent must be in the range [0.0, 1.0]." }            this.availableMemoryPercentage = percent            this.memoryCache = null        }


2.memoryCachePolicy :

内存缓存策略,有4中策略;


3.diskCachePolicy: 

磁盘缓存策略,方式和内存策略一致;

CachePolicy.ENABLED : 可读可写
CachePolicy.READ_ONLY : 只读
CachePolicy.WRITE_ONLY : 只写
CachePolicy.DISABLED : 不可读不可写,即禁用

短视频首帧

        Coil还有特别特别项,支持短视频首帧图片加载。正常在项目中,如果该项目有短视频业务,在视频不播放的状态下,如何获取首帧图片?这个问题是很多公司思考的问题。

        大公司在处理视频首帧都是通过服务器跑的。这样,在视频集在列表展示只处理单张图片即可。针对某一个视频,特别是小公司的时候,Coil明显很友好,可以在接收的范围类,降低技术和服务器的成本。

依赖库的引入:

implementation("io.coil-kt:coil-video:1.2.2")//支持Video

添加VideoDecoder

        //创建 gif ImageLoader 实例        val imageLoader = ImageLoader.Builder(applicationContext)            .componentRegistry {               add(VideoFrameDecoder(context))            }.build()        //设置全局唯一实例        Coil.setImageLoader(imageLoader)

剩余的设置,都是通用设置,如果项目需要支持GIF、VideoFrame,可以同时支持进去,都是通过componentRegistry add添加,可以追加进去。


 

来源地址:https://blog.csdn.net/qq36246172/article/details/129764778

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯