在Glide中, 可以获取资源并修改它,然后返回被修改后的资源。通常变换操作是用来完成剪裁或对位图应用过滤器,但它也可以用于转换GIF动画,甚至自定义的资源类型。
Glide 提供了很多内置的变换,包括:
通过 类可以应用变换:
默认变换
大多数内置的变换都有静态的 import ,这是为 API 的流畅性考虑的。例如,你可以通过静态方法应用一个 变换:
Glide.with(fragment)
.apply(fitCenterTransform())
.into(imageView);
如果你正在使用 Generated API ,那么这些变换方法已经被内联了,所以使用起来甚至更为轻松:
可以查阅 页来获得更多 RequestOption
的相关信息。
多重变换
默认情况下,每个 调用,或任何特定转换方法(fitCenter()
, centerCrop()
, bitmapTransform()
etc)的调用都会替换掉之前的变换。
如果你想在单次加载中应用多个变换,请使用 MultiTransformation
类。
使用 :
Glide.with(fragment)
.load(url)
.transform(new MultiTransformation(new FitCenter(), new YourCustomTransformation())
.into(imageView);
请注意,你向 MultiTransformation
的构造器传入变换参数的顺序,决定了这些变换的应用顺序。
尽管 Glide 提供了各种各样的内置 实现,如果你需要额外的功能,你也可以实现你自己的 Transformation
。
BitmapTransformation
如果你只需要变换 Bitmap
,最好是从继承 BitmapTransformation
开始。BitmapTransformation
处理了一些基础的东西,包括提取和回收原始的 Bitmap,如果你的变换返回了一个新修改的 Bitmap 的话。
一个简单的实现看起来可能像这样:
public class FillSpace extends BitmapTransformation {
private static final String ID = "com.bumptech.glide.transformations.FillSpace";
private static final String ID_BYTES = ID.getBytes(STRING_CHARSET_NAME);
{@literal @Override}
public Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
if (toTransform.getWidth() == outWidth && toTransform.getHeight() == outHeight) {
return toTransform;
}
return Bitmap.createScaledBitmap(toTransform, outWidth, outHeight, /*filter=*/ true);
}
{@literal @Override}
return o instanceof FillSpace;
}
{@literal @Override}
public int hashCode() {
return ID.hashCode();
}
{@literal @Override}
public void updateDiskCacheKey(MessageDigest messageDigest)
throws UnsupportedEncodingException {
messageDigest.update(ID_BYTES);
}
}
尽管你的 Transformation
将几乎确定比这个示例更复杂,但它应该包含了相同的基本元素和复写方法。
必需的方法
请特别注意,对于任何 Transformation
子类,包括 BitmapTransformation
,你都有三个方法你 必须 实现它们,以使得磁盘和内存缓存正确地工作:
- equals()
- hashCode()
如果你的
Transformation
没有参数,通常使用一个包含完整包限定名的 static
final
String
来作为一个 ID,它可以构成 hashCode()
的基础,并可用于更新 updateDiskCacheKey()
传入的 MessageDigest
。如果你的 需要参数而且它会影响到 Bitmap
被变换的方式,它们也必须被包含到这三个方法中。
例如,Glide 的 RoundedCorners
变换接受一个 int
,它决定了圆角的弧度。它的equals()
, hashCode()
和 updateDiskCacheKey
实现看起来像这样:
不要忘记 equals() / hashCode()!
值得重申的一点是,为了让内存缓存正常地工作你是否必须实现 equals()
和 hashCode()
方法。很不幸,即使你没有复写这两个方法,BitmapTransformation
和 Transformation
也能通过编译,但这并不意味着它们能正常工作。我们正在探索一些方案,以使在 Glide 的未来版本中,使用默认的 equals()
和 hashCode
方法将抛出一个编译时错误。
重用变换
Transformation
的设计初衷是无状态的。因此,在多个加载中复用 Transformation
应当总是安全的。创建一次 Transformation
并在多个加载中使用它,通常是很好的实践。
ImageView的自动变换
在Glide中,当你为一个 ImageView 开始加载时,Glide可能会自动应用 或 CenterCrop ,这取决于view的 。如果 scaleType
是 CENTER_CROP
, Glide 将会自动应用 CenterCrop
变换。如果 scaleType
为 FIT_CENTER
或 CENTER_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
。
原文: