如何在Android中用Glide加载图片

801 阅读5分钟

在Android中用Glide加载图像

在本教程中,我们将学习如何使用Glide库从互联网(URL)或从Drawable 图像文件中加载图像到Android中的ImageView

前提条件

要完成本教程,读者应该。

  • 安装有[Android Studio]。
  • 对[Kotlin]编程语言和[XML]有良好的理解。
  • 熟悉[ViewBinding]。

目标

在本教程结束时,读者应该能够。

  • 理解什么是[Glide]。
  • XML 布局中添加一个[ImageView]。
  • 使用Glide 库加载图片。

简介

在Android应用程序中加载图像是很困难的,开发者不得不通过创建各种视觉表现库来解决这个问题,如GlidePicassoCoil图像加载器和Fresco。在这篇文章中,我们将进一步讨论Glide库。

什么是Glide?

Glide是一个用于Android的快速而有效的图像加载库,专注于平滑滚动。它提供了一个简单易用的应用编程接口(API),体面的性能和可扩展的资源解码管道,以及编程的资源池。

Glide支持获取、解码和显示视频剧照、图像和GIF动画图像。它的主要重点是使滚动和任何种类的图像列表尽可能的平滑和快速。另外,在你需要获取、调整大小和显示远程图像的地方,它也是成功的。

Glide的特点

Glide有以下特点。

  • 图像加载--这允许访问互联网上的图像或从一个可绘制的图像。
  • 圆形裁剪- 在圆形视图中显示图像。
  • 调整大小和缩放- 这指的是调整图像的大小。
  • 中心裁剪- 这是指通过重新取样对整个图像进行缩放。
  • 旋转和变换- 指从一个点改变图像的方向。
  • 内存和磁盘缓存- 确保不为每个特定请求下载图像。
  • 占位符- 当一个请求正在进行时显示的图像。
  • 错误图像- 当请求资源失败时显示的图像。
  • 渐变- 这是Glide提供的一个动画功能。

使用Glide比其他图像加载库的优势

  • 允许图像的全尺寸磁盘缓存。
  • Glide库的速度更快。
  • 提供了一个高效的多线程网络。
  • 提供各种编辑工具。
  • 它增强了图像的平滑滚动。
  • 它支持GIF动画。

第1步:在Android Studio中创建一个新项目

启动Android Studio并选择New Project ,然后选择Empty Activity project 。让我们把它命名为Glide

Creating Project

点击Finish ,等待它的构建。

第2步:将Glide添加到我们的项目中

在app-module级别的build.gradle 文件中添加以下依赖项。

implementation 'com.github.bumptech.glide:glide:4.12.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'

给你的项目添加互联网权限。

<uses-permission android:name="android.permission.INTERNET"/>

第3步:创建XML布局

在这一步,我们要设计由Buttons 和一个ImageView 组成的XML 布局。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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/imageView"
    android:layout_width="match_parent"
    android:layout_height="250dp"
    android:layout_marginStart="8dp"
    android:layout_marginTop="8dp"
    android:layout_marginEnd="8dp"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    tools:srcCompat="@tools:sample/avatars" />
<Button
    android:id="@+id/buttonUrl"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="8dp"
    android:layout_marginTop="24dp"
    android:text="URL"
    app:layout_constraintStart_toStartOf="@+id/imageView"
    app:layout_constraintTop_toBottomOf="@+id/imageView" />
<Button
    android:id="@+id/buttonResize"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="32dp"
    android:text="Resize Image"
    app:layout_constraintBottom_toBottomOf="@+id/buttonUrl"
    app:layout_constraintStart_toEndOf="@+id/buttonUrl"
    app:layout_constraintTop_toTopOf="@+id/buttonUrl" />
<Button
    android:id="@+id/buttonFitCenter"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="16dp"
    android:text="FitCenter"
    app:layout_constraintStart_toStartOf="@+id/buttonUrl"
    app:layout_constraintTop_toBottomOf="@+id/buttonUrl" />
<Button
    android:id="@+id/buttonCenterCrop"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="4dp"
    android:text="CenterCrop"
    app:layout_constraintBottom_toBottomOf="@+id/buttonFitCenter"
    app:layout_constraintStart_toEndOf="@+id/buttonFitCenter"
    app:layout_constraintTop_toTopOf="@+id/buttonFitCenter" />
<Button
    android:id="@+id/buttonDrawable"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="16dp"
    android:text="Drawable"
    app:layout_constraintStart_toStartOf="@+id/buttonFitCenter"
    app:layout_constraintTop_toBottomOf="@+id/buttonFitCenter" />
<Button
    android:id="@+id/buttonPlaceholder"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="8dp"
    android:text="Placeholder"
    app:layout_constraintBottom_toBottomOf="@+id/buttonDrawable"
    app:layout_constraintStart_toEndOf="@+id/buttonDrawable"
    app:layout_constraintTop_toTopOf="@+id/buttonDrawable" />
<Button
    android:id="@+id/buttonError"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="8dp"
    android:text="Error"
    app:layout_constraintBottom_toBottomOf="@+id/buttonCircleCrop"
    app:layout_constraintStart_toEndOf="@+id/buttonCircleCrop"
    app:layout_constraintTop_toTopOf="@+id/buttonCircleCrop" />
<Button
    android:id="@+id/buttonCache"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="16dp"
    android:text="Cache"
    app:layout_constraintStart_toStartOf="@+id/buttonDrawable"
    app:layout_constraintTop_toBottomOf="@+id/buttonDrawable" />
<Button
    android:id="@+id/buttonCircleCrop"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="8dp"
    android:text="CircleCrop"
    app:layout_constraintBottom_toBottomOf="@+id/buttonCache"
    app:layout_constraintStart_toEndOf="@+id/buttonCache"
    app:layout_constraintTop_toTopOf="@+id/buttonCache" />
<Button
    android:id="@+id/buttonTarget"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="8dp"
    android:text="Target"
    app:layout_constraintStart_toStartOf="@+id/buttonCache"
    app:layout_constraintTop_toBottomOf="@+id/buttonCache" />
</androidx.constraintlayout.widget.ConstraintLayout>

注意:本教程中使用的样本图片可以在这里找到。

第4步:实现Glide功能

从一个URL加载图片

Glide允许显示来自链接(URL)的图片,而不需要下载它们。

val resizeImage = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRe0O0260hzKyKursZUTtZAxECP0gSVJ2JXwQ&usqp=CAU"
binding.buttonUrl.setOnClickListener {
Glide.with(this)
    .load(resizeImage)
    .into(binding.imageView)
}

加载可绘制的图像

Glide允许将Drawable 图像文件加载到ImageViews 。这可以通过在你的活动中添加以下几行代码来实现。

binding.buttonDrawable.setOnClickListener {
Glide.with(this)
    .load(R.drawable.image)
    .into(binding.imageView)
}

变换

Glide中的变换涉及到获取一个图像资源,改变其外观,并返回改变后的资源。变换也被用来裁剪和应用图像的过滤器。

a) 中心裁剪

它对图像进行缩放,最终目的是使图像的宽度与给定的宽度ImageView ,图像的高度大于给定的高度,或者反过来。这种方法将图像裁剪成适合于给定的ImageView 的尺寸。

中心裁剪是通过使用centerCrop() 方法实现的。

binding.buttonCenterCrop.setOnClickListener{
Glide.with(this)
    .load(R.drawable.codingtable)
    .centerCrop()
    .into(binding.imageView)
}

b) FitCenter

对图像进行一致的缩放,最终目的是使其中一个测量值与给定的ImageView ,另一个测量值与给定的ImageView 不完全相同。

它是通过使用fitCenter() 方法实现的。

binding.buttonFitCenter.setOnClickListener {
Glide.with(this)
    .load(R.drawable.codingtable)
    .fitCenter()
    .into(binding.imageView)
}

c) CircleCrop

就像FitCenter变换一样,circleCrop 将图像在ImageView 内进行缩放,但所得到的图像被转换为一个圆形轮廓。

它是通过使用circleCrop() 方法来实现的。

private val image = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT5_f-3Npwnj40B6u8O8WmcX8swxRqUS8ncQg&usqp=CAU"
binding.buttonCircleCrop.setOnClickListener {
Glide.with(this)
    .load(image)
    .circleCrop()
    .into(binding.imageView)
}

占位符

占位符是在请求过程中显示的图像。一旦请求成功完成,占位符就消失了。然而,如果在任何情况下,请求加载失败,并且没有设置错误drawable ,占位符将持续存在于ImageView

// invalid url for testing
private val image = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT5_f-3Npwnj40B6u8O8WmcX8swxRqUS8ncQ"
binding.buttonPlaceholder.setOnClickListener {
Glide.with(this)
    .load(image)
    .placeholder(R.drawable.placeholder)
    .into(binding.imageView)
}

错误图像

错误图像是在请求的URL模型为空或请求的资源永久无法加载时显示的图像。

binding.buttonError.setOnClickListener {
Glide.with(this)
    .load("https://encrypted-tbn0.gstatic.com/images?q=tbn")
    .error(R.drawable.error)
    .into(binding.imageView)
}

图像缓存

在开始一个新的图像请求之前,Glide检查几层缓存。

  1. 活动资源- 检查请求的图像是否在其他视图中可见。
  2. 内存缓存- 检查该图像是否最近被加载并且仍然在内存中。
  3. 数据- 此图像中的数据之前是否从写入的磁盘缓存中获得?

只从缓存中加载

private val resizeImage = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRe0O0260hzKyKursZUTtZAxECP0gSVJ2JXwQ&usqp=CAU"
binding.buttonCache.setOnClickListener {
Glide.with(this)
    .load(resizeImage)
    .onlyRetrieveFromCache(true)
    .into(binding.imageView)
}

目标

目标作为请求和发送请求的对象之间的接口。目标的目的是显示占位符,加载图像,并为每个请求的图像分配正确的尺寸。

binding.buttonTarget.setOnClickListener {
Glide.with(this)
    .asGif()
    .load(R.drawable.meditation)
    .into(object : SimpleTarget<GifDrawable>(){
        override fun onResourceReady(
            resource: GifDrawable,
            transition: Transition<in GifDrawable>?
        ){
            resource.start()
            binding.imageView.setImageDrawable(resource)
        }
    })
}

项目演示

Demo Project

总结

Glide是一个强大的图像加载库,易于使用。