查看原文
其他

Coil:为Kotlin而生的图片加载库

AndroidPub 2022-05-15

Coil 基于 Coroutine 实现图片加载,非常适合在 Kotlin/Android 项目中使用:

  • 性能出众:图片加载性能好
  • 体积较小:其包体积与Picasso相当,显著低于Glide和Fresco,仅仅只有1500个方法,但是在功能上却不输于其他同类库
  • 简单易用:配合Kotlin扩展方法等语法优势,API简单易用
  • 技术先进:基于Coroutine、OkHttp、Okio、AndroidX等先端技术开发,确保了技术上的先进性
  • 丰富功能:缓存管理(MemCache、DiskCache)、动态采样(Dynamic image sampling)、加载中暂停/终止等功能有助于提高图片加载效率

引入Coil

build.gradle

dependencies {
    implementation 'io.coil-kt:coil:$latested_version' //目前最新是1.2.1
                  ︙
}

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="kaleidot725.coilsample">
    <uses-permission android:name="android.permission.INTERNET" />
                                ︙
</manifest>

使用ImageView加载图片

我们在 activity_main.xml 中声明 ImageView 后, 使用 Coil 为其加载图片:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">


    <ImageView
        android:id="@+id/image_view"
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:layout_gravity="center"
        android:background="#CCCCCC"/>


    <Button
        android:id="@+id/reload_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right|bottom"
        android:layout_margin="16dp"
        android:text="Reload"/>

</FrameLayout>

普通加载

val url = "https://img-blog.csdnimg.cn/20210124002108308.png"
val imageView = findViewById<ImageView>(R.id.image_view)
val reloadButton = findViewById<Button>(R.id.reload_button)
reloadButton.setOnClickListener {
    val disposable = imageView.load(url)
    disposable.dispose()
}

  • 通过扩展方法 load 加载 url
  • 除了 String 以外,还支持 HttpUrl 、Url、 File、 DrawableRes Int 、Drawable、 Bitmap等各种类型的加载
  • load 返回 Disposable,可以终止加载
普通加载

crossfade 淡入效果加载

val url = "https://img-blog.csdnimg.cn/20210124002108308.png"
val imageView = findViewById<ImageView>(R.id.image_view)
val reloadButton = findViewById<Button>(R.id.reload_button)
reloadButton.setOnClickListener {
 imageView.load(url) {
         crossfade(true)
    }
}


    

通过kotlin的尾lambda语法,load(url) {... }内部启动crossfade

crossfade

crossfade 动画时间设置

val url = "https://img-blog.csdnimg.cn/20210124002108308.png"
val imageView = findViewById<ImageView>(R.id.image_view)
val reloadButton = findViewById<Button>(R.id.reload_button)
reloadButton.setOnClickListener {
    imageView.load(url) {
        crossfade(3000)
    }
}
crossfade(3000)

placeholder 设置占位图

val url = "https://img-blog.csdnimg.cn/20210124002108308.png"
val imageView = findViewById<ImageView>(R.id.image_view)
val reloadButton = findViewById<Button>(R.id.reload_button)
reloadButton.setOnClickListener {
    imageView.load(url) {
        placeholder(R.drawable.placeholder)
        crossfade(3000)
    }
}
placeholder

error 设置加载失败时的图片

val url = "https://notfound.png"
val imageView = findViewById<ImageView>(R.id.image_view)
val reloadButton = findViewById<Button>(R.id.reload_button)
reloadButton.setOnClickListener {
    imageView.load(url) {
        error(R.drawable.error)
    }
}

error

Transformations 图片变换

图片加载时,可以通过 transformations 对图片进行变换处理 目前支持 BlurCropCircleGrayscaleRouded corners 等四种变换效果

Blur 高斯模糊

通过 BlurTransformation 类可以实现时下流行的毛玻璃效果。

val url = "https://img-blog.csdnimg.cn/20210124002108308.png"
val imageView = findViewById<ImageView>(R.id.image_view)
val reloadButton = findViewById<Button>(R.id.reload_button)
reloadButton.setOnClickListener {
     imageView.load(url) {
         transformations(BlurTransformation(context = applicationContext, radius = 5f, sampling = 5f))
    }
}
blur

CropCircle 圆形切图

圆形头像、圆形ICON也是非常常见的设计需求,CircleCropTransformation 类则可帮助我们实现。

 val url = "https://img-blog.csdnimg.cn/20210124002108308.png"
    val imageView = findViewById<ImageView>(R.id.image_view)
    val reloadButton = findViewById<Button>(R.id.reload_button)
    reloadButton.setOnClickListener {
        imageView.load(url) {
            transformations(CircleCropTransformation())
        }
    }
CropCircle

Grayscale 灰度变换

特殊节日或事件的时候,难免需要将图片变灰展示。而 GrayscaleTransformation 类则是对应的转换类。

val url = "https://img-blog.csdnimg.cn/20210124002108308.png"
val imageView = findViewById<ImageView>(R.id.image_view)
val reloadButton = findViewById<Button>(R.id.reload_button)
reloadButton.setOnClickListener {
    imageView.load(url) {
            transformations(GrayscaleTransformation())
    }
}
Grayscale

Rounded Corners 圆角效果

除了带火了毛玻璃效果,iOS上推出的圆角效果在设计界也大受欢迎。RoundedCornersTransformation 类则可以实现圆角矩形的变换。

val url = "https://img-blog.csdnimg.cn/20210124002108308.png"
val imageView = findViewById<ImageView>(R.id.image_view)
val reloadButton = findViewById<Button>(R.id.reload_button)
reloadButton.setOnClickListener {
    imageView.load(url) {
        transformations(RoundedCornersTransformation(topRight = 10f, topLeft = 10f, bottomLeft =  10f, bottomRight =  10f))
    }
Rounded Corners

使用 ImageLoader 加载图片

除了上面介绍的在 load(url) 时,在尾lambda内进行各种配置以外,还可以通过创建 ImageLoader ,复用配置。

上面介绍的所有配置都可以在 ImageLoader 中进行,此外,还可以进行 Memory CacheBitmap Pooling 等更加多样化的配置:

val imageLoader = ImageLoader(applicationContext) {
    crossfade(true)
    placeholder(R.drawable.placeholder)
    error(R.drawable.error)
    availableMemoryPercentage(0.1)
    bitmapPoolPercentage(0.1)
}

如上,我们创建 imageLoader 实例后,后续可以在 load(url) 时,通过指定此实例复用上面的配置

val url = "https://notfound.png"
val imageView = findViewById<ImageView>(R.id.image_view)
val reloadButton = findViewById<Button>(R.id.reload_button)
reloadButton.setOnClickListener {
    imageView.load(url, imageLoader)
}

我们甚至可以通过Coil.setDefaultImageLoader,指定全局的默认 ImageLoader,避免每次 load 时单独指定

  Coil.setDefaultImageLoader(ImageLoader(applicationContext) {
        crossfade(true)
        placeholder(R.drawable.placeholder)
        error(R.drawable.error)
        availableMemoryPercentage(0.1)
        bitmapPoolPercentage(0.1)
    })

    val url = "https://notfound.png"
    val imageView = findViewById<ImageView>(R.id.image_view)
    val reloadButton = findViewById<Button>(R.id.reload_button)
    reloadButton.setOnClickListener {
        imageView.load(url)
    }

接语

Coil 配合Kotlin强大的语法特性打造了优秀的使用体验,功能上完全对标竞品毫不逊色。可以预见,随着Kotlin在Andorid开发中比重的日益提升,Coil必将超越竞品成为图片加载库的第一选项。

参考

https://coil-kt.github.io/coil/




推荐阅读:


打造一个 Compose 版的俄罗斯方块


ViewPager中的Fragment如何实现懒加载?


Kotlin 1.5 来了,Inline classes 了解一下?


当Jetpack Compose 遇到 Navigation




↓关注公众号↓↓添加微信交流↓



您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存