通过这篇文章你会学到什么?

通过这个文章,我会通过一些代码片段来告诉你怎么使用coil库来加载图片。还有综合Glide和Picasso做一些代码使用的对比。

coil是一套完全基于kotlin语言的图片加载库,这使得我们必须要使用kotlin语言开发的项目才能使用它。

首先,coil必须支持Java8才行,如下我们在配置中这样设置:

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

coil有四个库我们可以依赖,每一个都有他们自己的目的,不过我们只用到如下两种即可:

1、io.coil-kt: Coil :如果你没有在应用程序中使用依赖项注入或维护任何Coil实例,那么最好使用此库。

2、io.coil-kt: coil-base: 这个是最基本的库,不包括io-coil-kt:Coil库,如果你正在使用依赖项注入来注入Coil实例,请优先使用此库。

//Singleton artifact
implementation "io.coil-kt:coil:1.1.0"
//Base artifact without singleton
implementation "io.coil-kt:coil-base:1.1.0"

使用起来

现在我们已经准备好了,看看如何使用吧!Have a look!

imageView.load("https://www.example.com/image.jpg")  

我们发现用起来是如此的简单,直接用iamgeView直接load即可,相信感兴趣的同学肯定想知道为什么ImageView会有load的方法呢?

我们点进去就可以看到了,这其中coil帮我们做了一次扩展,对于ImageView进行了一次扩展:

package coil

import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.net.Uri
import android.widget.ImageView
import androidx.annotation.DrawableRes
import coil.request.Disposable
import coil.request.ImageRequest
import coil.request.ImageResult
import coil.util.CoilUtils
import okhttp3.HttpUrl
import java.io.File

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

这里面的loadAny方法需要我们传递Url或者bitmap、drawableResId、file,coil已经做得很好了,用起来也是非常方便呢!

Placeholder and error images

其他的图片加载库也是包含了这些功能,那coil也是可以实现的,方式更为简单:

fun loadWithCoil(imageView: ImageView, imageUrl: String){
    imageView.load(imageUrl){
        placeholder(R.drawable.placeholder)
        error(R.drawable.error)
    }
}

Preload images

Coil允许我们使用协程去更高效的下载图片,我们能够使用get的协程标注挂起方法来实现:

val image = Coil.get(imageUrl)

通过这个方法我们可以下载下来drawable。

Callbacks

回调,用Glide的同学肯定也是很清楚怎么使用glide来实现回调了吧,我们看看coil会给我们带来怎么样的惊喜呢?

fun coilWithCallbacks(){
    Coil.load(context, "https://www.example.com/image.jpg") {
        target { drawable ->
            // Handle the successful result.
        }
    }
}

是不是感觉很简单,很容易看得懂呢!

这里的target有三个类型:

1、Target:被用于请求图片的不是一个连接

2、ViewTarget:被用于当请求的是一个连接,如展示一个默认图知道下载图片完成

3、possibleViewTarget:被用于如果有一个图片池

Transformations

转换是Coil的一个亮点,用起来非常简单,Out of a box,Coil包括了四种转换方式:blur(模糊)、circle crop(圆形)、grayscale(灰度)、rounded(圆角),下面展示一下如何使用:

fun loadWithCoil(imageView: ImageView, imageUrl: String){
    imageView.load(imageUrl){
        placeholder(R.drawable.gradient_place_details)
        error(R.drawable.gradient_place_details)
        transformations(CircleCropTransformation())
    }
}

Cancel Request

取消请求,顾名思义,就是图片还没有请求回来我们在特定情况下需要进行取消。

有效的利用资源是展示一个App最好的手段,Coil,默认的在view脱离了之后会自动进行取消,或者context已经被销毁了;

又或者另一个请求又在这个view上发生了,Coil覆盖了所有的内存泄露的情况,已经做的很全面了。

但是也有情况是我们自己要取消请求的,基于此目的,Coil返回了RequestDisposable对象,我们可以直接进行取消,如下:

val disposable = imageView.load("https://www.example.com/image.jpg")
// Cancel the request.
disposable.dispose() 

Image Sampling

图片采集是加载图片最先进的技术被用于加载图片的质量基于图片view的大小的,假设硬盘上有500*500大小的图片,那么在Coil加载这张图片的时候,

会加载100*100大小的图片作为默认图展示,直到原图片加载完成。我们可以使用crossfade随时开启这个功能,如下:

imageView.load(imageUrl){
crossfade
(true)
}

Migration from Glide/Picasso

做一下简单的对比:

Basic usage:

// Glide
    Glide.with(context)
    .load(url)
    .into(imageView)

// Picasso
    Picasso.get()
    .load(url)
    .into(imageView)

// Coil
    imageView.load(url)

Callback requests

// Glide (has optional callbacks for start and error)
Glide.with(context)
    .load(url)
    .into(object : CustomTarget<Drawable>() {
        override fun onResourceReady(resource: Drawable, transition: Transition<Drawable>) {
            // Handle the successful result.
        }

        override fun onLoadCleared(placeholder: Drawable) {
            // Remove the drawable provided in onResourceReady from any Views and ensure no references to it remain.
        }
    })

// Picasso
Picasso.get()
    .load(url)
    .into(object : BitmapTarget {
        override fun onBitmapLoaded(bitmap: Bitmap, from: Picasso.LoadedFrom) {
            // Handle the successful result.
        }

        override fun onBitmapFailed(e: Exception, errorDrawable: Drawable?) {
            // Handle the error drawable.
        }

        override fun onPrepareLoad(placeHolderDrawable: Drawable?) {
            // Handle the placeholder drawable.
        }
    })

// Coil (has optional callbacks for start and error)
Coil.load(context, url) {
    target { drawable ->
        // Handle the successful result.
    }
}

Custom requests

imageView.scaleType = ImageView.ScaleType.FIT_CENTER

// Glide
Glide.with(context)
    .load(url)
    .placeholder(placeholder)
    .fitCenter()
    .into(imageView)

// Picasso
Picasso.get()
    .load(url)
    .placeholder(placeholder)
    .fit()
    .into(imageView)

// Coil (autodetects the scale type)
imageView.load(url) {
    placeholder(placeholder)
}

完结,对比而言,coil的可使用性还是很高的,特别对于kotlin开发的代码切合度非常高,使用起来非常方便!!!

05-16 08:38