在Glide中, 可以获取资源并修改它,然后返回被修改后的资源。通常变换操作是用来完成剪裁或对位图应用过滤器,但它也可以用于转换GIF动画,甚至自定义的资源类型。

Glide 提供了很多内置的变换,包括:

通过 类可以应用变换:

默认变换

大多数内置的变换都有静态的 import ,这是为 API 的流畅性考虑的。例如,你可以通过静态方法应用一个 变换:

  1. Glide.with(fragment)
  2. .apply(fitCenterTransform())
  3. .into(imageView);

如果你正在使用 Generated API ,那么这些变换方法已经被内联了,所以使用起来甚至更为轻松:

可以查阅 页来获得更多 RequestOption 的相关信息。

多重变换

默认情况下,每个 调用,或任何特定转换方法(fitCenter(), centerCrop(), bitmapTransform() etc)的调用都会替换掉之前的变换。

如果你想在单次加载中应用多个变换,请使用 MultiTransformation 类。

使用 :

  1. Glide.with(fragment)
  2. .load(url)
  3. .transform(new MultiTransformation(new FitCenter(), new YourCustomTransformation())
  4. .into(imageView);

请注意,你向 MultiTransformation 的构造器传入变换参数的顺序,决定了这些变换的应用顺序。

尽管 Glide 提供了各种各样的内置 实现,如果你需要额外的功能,你也可以实现你自己的 Transformation

BitmapTransformation

如果你只需要变换 Bitmap,最好是从继承 BitmapTransformation 开始。BitmapTransformation 处理了一些基础的东西,包括提取和回收原始的 Bitmap,如果你的变换返回了一个新修改的 Bitmap 的话。

一个简单的实现看起来可能像这样:

  1. public class FillSpace extends BitmapTransformation {
  2. private static final String ID = "com.bumptech.glide.transformations.FillSpace";
  3. private static final String ID_BYTES = ID.getBytes(STRING_CHARSET_NAME);
  4. {@literal @Override}
  5. public Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
  6. if (toTransform.getWidth() == outWidth && toTransform.getHeight() == outHeight) {
  7. return toTransform;
  8. }
  9. return Bitmap.createScaledBitmap(toTransform, outWidth, outHeight, /*filter=*/ true);
  10. }
  11. {@literal @Override}
  12. return o instanceof FillSpace;
  13. }
  14. {@literal @Override}
  15. public int hashCode() {
  16. return ID.hashCode();
  17. }
  18. {@literal @Override}
  19. public void updateDiskCacheKey(MessageDigest messageDigest)
  20. throws UnsupportedEncodingException {
  21. messageDigest.update(ID_BYTES);
  22. }
  23. }

尽管你的 Transformation 将几乎确定比这个示例更复杂,但它应该包含了相同的基本元素和复写方法。

必需的方法

请特别注意,对于任何 Transformation 子类,包括 BitmapTransformation,你都有三个方法你 必须 实现它们,以使得磁盘和内存缓存正确地工作:

    • equals()
    • hashCode()

如果你的 Transformation 没有参数,通常使用一个包含完整包限定名的 static final String 来作为一个 ID,它可以构成 hashCode() 的基础,并可用于更新 updateDiskCacheKey() 传入的 MessageDigest。如果你的 需要参数而且它会影响到 Bitmap 被变换的方式,它们也必须被包含到这三个方法中。

例如,Glide 的 RoundedCorners 变换接受一个 int,它决定了圆角的弧度。它的equals(), hashCode()updateDiskCacheKey 实现看起来像这样:

不要忘记 equals() / hashCode()!

值得重申的一点是,为了让内存缓存正常地工作你是否必须实现 equals()hashCode() 方法。很不幸,即使你没有复写这两个方法,BitmapTransformationTransformation 也能通过编译,但这并不意味着它们能正常工作。我们正在探索一些方案,以使在 Glide 的未来版本中,使用默认的 equals()hashCode 方法将抛出一个编译时错误。

重用变换

Transformation 的设计初衷是无状态的。因此,在多个加载中复用 Transformation 应当总是安全的。创建一次 Transformation 并在多个加载中使用它,通常是很好的实践。

ImageView的自动变换

在Glide中,当你为一个 ImageView 开始加载时,Glide可能会自动应用 或 CenterCrop ,这取决于view的 。如果 scaleTypeCENTER_CROP , Glide 将会自动应用 CenterCrop 变换。如果 scaleTypeFIT_CENTERCENTER_INSIDE ,Glide会自动使用 FitCenter 变换。

当然,你总有权利覆写默认的变换,只需要一个带有 Transformation 集合的 RequestOptions 即可。另外,你也可以通过使用 确保不会自动应用任何变换。

自定义资源

因为 Glide 4.0 允许你指定你将解码的资源的父类型,你可能无法确切地知道将会应用何种变换。例如,当你使用 (或就是普通的 with() ,因为 asDrawable() 是默认情形)来加载 Drawable 资源时,你可能会得到 BitmapDrawable 子类,也有可能得到 子类。

为了确保你添加到 RequestOptions 中的任何变换都会被使用,Glide将 Transformation 添加到一个Map中保存,其Key为你提供变换的资源类型。当资源被成功解码时,Glide使用这个Map来取回对应的 Transformation

Glide可以将 Bitmap Transformation应用到 BitmapDrawable , GifDrawable , 以及 Bitmap 资源上,因此通常你只需要编写和应用 Bitmap Transformation 。然而,如果你添加了额外的资源类型,你可能需要考虑派生 RequestOptions 类,并让你的资源类型能应用Glide内置的 Bitmap

原文: