标签:使用详解 getwidth memory 顺序 要求 资源文件 设备 ges The
本文所使用的Glide版本为3.7.0
dependencies {
compile ‘com.github.bumptech.glide:glide:3.7.0‘
compile ‘com.android.support:support-v4:23.2.1‘
}
Glide 也支持 Maven 项目形式:
<dependency>
<groupId>com.github.bumptech.glide</groupId>
<artifactId>glide</artifactId>
<version>3.7.0</version>
</dependency>
<dependency>
<groupId>com.google.android</groupId>
<artifactId>support-v4</artifactId>
<version>r7</version>
</dependency>
github地址:https://github.com/bumptech/glide 如果是Eclipse使用去下载Glide的jar在项目中使用就可以了,jar的链接https://github.com/bumptech/glide/releases
String url = "http://img1.dzwww.com:8080/tupian_pl/20150813/16/7858995348613407436.jpg";
ImageView imageView = (ImageView) findViewById(R.id.imageView);
Glide.with(context)
.load(url)
.into(imageView);
- with(Context context) - 需要上下文,这里还可以使用 Activity、FragmentActivity、android.support.v4.app.Fragment、android.app.Fragment 的对象。将 Activity/Fragment 对象作为参数的好处是,图片的加载会和 Activity/Fragment 的生命周期保持一致,例如:onPaused 时暂停加载,onResume 时又会自动重新加载。所以在传参的时候建议使用 Activity/Fragment 对象,而不是 Context。
String url = "http://img1.dzwww.com:8080/tupian_pl/20150813/16/7858995348613407436.jpg";
ImageView imageView = (ImageView) findViewById(R.id.imageView);
Glide.with(context)
.load(url)
.placeholder(R.drawable.place_image)//图片加载出来前,显示的图片
.error(R.drawable.error_image)//图片加载失败后,显示的图片
.into(imageView);
注:这里需要注意一点,placeholder() 和 error() 的参数都是只支持 int 和 Drawable 类型的参数,这种设计应该是考虑到使用本地图片比网络图片更加合适做占位图。
Glide.with( context )
.load( url )
.thumbnail( 0.2f )
.into( imageView );
注:应用于请求的设置也将应用于缩略图。使用 thumbnail() 方法来设置是简单粗暴的,但是如果缩略图需要通过网络加载相同的全尺寸图片,就不会很快的显示了。所以 Glide 提供了另一种防止去加载缩略图,先看代码
private void loadImageThumbnailRequest(){
// setup Glide request without the into() method
DrawableRequestBuilder<String> thumbnailRequest = Glide.with( context ).load( url );
// pass the request as a a parameter to the thumbnail request
Glide.with( context )
.load( url )
.thumbnail( thumbnailRequest )
.into( imageView );
}
与第一种方式不同的是,这里的第一个缩略图请求是完全独立于第二个原始请求的。该缩略图可以是不同的资源图片,同时也可以对缩略图做不同的转换,等等...
Glide.with(context)
.load(url)
.crossFade()//或者使用 dontAnimate() 关闭动画
.placeholder(R.drawable.place_image)
.error(R.drawable.error_image)
.into(imageView);
PS:Glide 是可以自定义动画效果的,这个在后面会讲解
Glide.with(context)
.load(url)
.override(width,height)//这里的单位是px
.into(imageView);
在设置图片到 ImageView 的时候,为了避免图片被挤压失真,ImageView 本身提供了 ScaleType 属性,这个属性可以控制图片显示时的方式,具体的属性使用还是去搜索吧!Glide 也提供了两个类似的方法 CenterCrop() 和 FitCenter(),CenterCrop() 方法是将图片按比例缩放到足矣填充 ImageView 的尺寸,但是图片可能会显示不完整;而 FitCenter() 则是图片缩放到小于等于 ImageView 的尺寸,这样图片是显示完整了,但是 ImageView 就可能不会填满了。
注:其实 Glide 的 CenterCrop() 和 FitCenter() 这两个方法分别对应 ImageView 的 ScaleType 属性中的 CENTER_CROP 和 FIT_CENTER 命名基本一致。
Glide.with(context)
.load(url)
.skipMemoryCache(true)
.diskCacheStrategy( DiskCacheStrategy.NONE )
.into(imageView);
上面这段代码将内存缓存和磁盘缓存都禁用了,这里使用枚举 DiskCacheStrategy.NONE 将磁盘缓存禁用了,这里涉及到了自定义磁盘缓存行为,我们接下来就讲解这个。
DiskCacheStrategy 的枚举意义:这只是举个例子而已
- DiskCacheStrategy.NONE 什么都不缓存
- DiskCacheStrategy.SOURCE 只缓存全尺寸图
- DiskCacheStrategy.RESULT 只缓存最终的加载图
- DiskCacheStrategy.ALL 缓存所有版本图(默认行为)
Glide.with(context)
.load(url)
.diskCacheStrategy( DiskCacheStrategy.SOURCE )
.into(imageView);
//设置 HIGH 优先级
Glide.with( context )
.load( highPriorityImageUrl )
.priority (Priority.HIGH )
.into( imageView );
//设置 LOW 优先级
Glide.with( context )
.load( lowPriorityImageUrl )
.priority( Priority.LOW )
.into( imageView );
这里有一点需要注意,优先级并不是完全严格遵守的。Glide 将会用他们作为一个准则,尽可能的处理这些请求,但是不能保证所有的图片都会按照所有要求的顺序加载。
- Priority.LOW
- Priority.NORMAL
- Priority.HIGH
- Priority.IMMEDIAT
String gifUrl = "http://i2.mhimg.com/M00/0E/AE/CgAAilTPWJ2Aa_EIACcMxiZi5xE299.gif";
Glide.with( context )
.load( gifUrl )
.placeholder( R.drawable.default )
.error( R.drawable.error )
.into( imageView );
这段代码还有点问题,如果加载的不是一张 gif 图的话,是没有办法显示的。
Glide.with( context )
.load( gifUrl )
.asGif()
.error( R.drawable.error )
.into( imageView );
做以上修改,如果图片类型不是 Gif 图的话就会当作 load 失败来处理,因此 error() 会被回调。即使这个url的图片是好的,也是不会显示的。当然,如果你想显示 Gif 但只是向现实静态的图片你就可以这么做
Glide.with( context )
.load( gifUrl )
.asBitmap()
.error( R.drawable.error )
.into( imageView );
仅仅是显示 Gif 的第一帧图像,这样就可以保证图片的正常显示了。还有一个神奇的功能,Glide 还能显示视频!But...只能够显示手机本地的视频,要是向现实网络上的视频的话,还是另寻他法吧!
String filePath = "/storrage/emulated/0/Pictures/video.mp4";
Glide.with( context )
.load( Uri.fromFile( new File( filePath ) ) )
.into( imageView );
Glide 的基础使用就讲解到这了。
其实对于 Target 可以简单的理解为回调,本身就是一个 interface,Glide本身也为我们提供了很多 Target
private SimpleTarget<Bitmap> mSimpleTarget = new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> animation) {
mImageView.setImageBitmap(resource);
}
};
private void loadImageSimpleTarget() {
Glide.with( thi s)
.load( mUrl )
.asBitmap()
.into( mSimpleTarget );
}
首先创建了一个 SimpleTarget 的对象并且实现了 onResourceReady() 方法,看方法名能知道是图片加载完之后会调用该方法,参数就有我们需要的 Bitmap 。而使用 SimpleTarget 的对象的时候就像使用 ImageView 一样,作为参数传给 into() 方法就行了,Glide 会内部去处理并返回结果给任何一个对象。这里我们为了防止加载 Gif 、 Video 或者一些位置资源时与 mSimpleTarget 冲突,所以我们调用了 asBitmap() 方法,使其只能返回 Bitmap 对象。这里就有个问题了,如果我需要改变图片的大小怎么办?这点小问题 Glide 还是有考虑到的,加入原尺寸 1000x1000 的图片,我们显示的时候只需要是 500x500 的尺寸来节省时间和内存,你可以在 SimpleTarget 的回调声明中指定图片的大小。
private SimpleTarget<Bitmap> mSimpleTarget = new SimpleTarget<Bitmap>(500,500) {
@Override
public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> animation) {
mImageView.setImageBitmap(resource);
}
};
从代码中可以看到 SimpleTarget 的对象的声明没有使用匿名对象,而是单独的声明了一个变量,这里是故意这么做的,如果使用匿名内部类的方式创建 SimpleTarget 的对象,这样会增大该对象在 Glide 完成图片请求之前就被回收的可能性。还记得前面说过 with() 方法传入 Activity 或者 Fragment 时 Glide 的图片加载会与他们的生命周期关联起来,但是如果我们使用 Target 的话,这个 Target 就有可能独立于他们的生命周期以外,这时候我们就需要使用 context.getApplicationContext() 的上下文了,这样只有在应用完全停止时 Glide 才会杀死这个图片请求。代码如下
Glide.with(mContext.getApplicationContext())
.load(mUrl)
.asBitmap()
.into(target);
public class CustomView extends FrameLayout {
private ImageView mImageView;
public CustomView(Context context) {
super(context);
}
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mImageView = new ImageView(getContext());
addView(mImageView , LayoutParams.MATCH_PARENT , LayoutParams.MATCH_PARENT);
}
public void setImage(Drawable drawable){
mImageView.setImageDrawable(drawable);
}
}
上面这个例子就没有办法直接使用 .into() ,如果我们使用 ViewTarget 实现呢!
public void loadImageTarget(Context context){
CustomView mCustomView = (CustomView) findViewById(R.id.custom_view);
ViewTarget viewTarget = new ViewTarget<CustomView,GlideDrawable>( mCustomView ) {
@Override
public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) {
this.view.setImage(resource);
}
};
Glide.with(context)
.load(mUrl)
.into(viewTarget);
}
在 target 的 onResourceReady 回调方法中使用自定义 view 自己的方法去设置图片,可以看到在创建 ViewTarget 的时候传入了 CustomView 的对象。还有其他Target的使用这里就不一一讲述了,例如 AppWidgetTarget 、 NotificationTarget ...
public class RoundTransformation extends BitmapTransformation {
private float radius = 0f;
public RoundTransformation(Context context) {
this(context, 4);
}
public RoundTransformation(Context context, int px) {
super(context);
this.radius = px;
}
@Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
return roundCrop(pool, toTransform);
}
private Bitmap roundCrop(BitmapPool pool, Bitmap source) {
if (source == null)
return null;
Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
if (result == null) {
result = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(result);
Paint paint = new Paint();
paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
paint.setAntiAlias(true);
RectF rectF = new RectF(0f, 0f, source.getWidth(), source.getHeight());
canvas.drawRoundRect(rectF, radius, radius, paint);
return result;
}
@Override
public String getId() {
return getClass().getName() + Math.round(radius);
}
}
现在我们有了自己的 Transformation 就可以来看看怎么使用了。调用 .transform() 方法,将自定义的 Transformation 的对象作为参数传递进去就可以使用你的 Transformation 了,这里也可以使用 .bitmaoTransform() 但是它只能用于 bitmap 的转换。
Glide.with(context)
.load(mUrl)
.transform(new RoundTransformation(context , 20))
//.bitmapTransform( new RoundTransformation(context , 20) )
.into(mImageView);
如果我们需要同时执行多个 Transformation 的话,我们不能使用链式的形式多次调用 .transform() 或 .bitmapTransform() 方法,即使你调用了,之前的配置就会被覆盖掉!我们可以直接传递多个转换对象给 .transform() 或 .bitmapTransform() 。
Glide.with(context)
.load(mUrl)
.transform(new RoundTransformation(context , 20) , new RotateTransformation(context , 90f))
.into(mImageView);
这段代码中我们把一个图片切圆角,然后做了顺时针旋转90度处理。下面是旋转处理的代码
public class RotateTransformation extends BitmapTransformation {
private float rotateRotationAngle = 0f;
public RotateTransformation(Context context, float rotateRotationAngle) {
super( context );
this.rotateRotationAngle = rotateRotationAngle;
}
@Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
Matrix matrix = new Matrix();
matrix.postRotate(rotateRotationAngle);
return Bitmap.createBitmap(toTransform, 0, 0, toTransform.getWidth(), toTransform.getHeight(), matrix, true);
}
@Override
public String getId() {
return getClass().getName() + Math.round(rotateRotationAngle);
}
}
注:这里需要注意一点 .centerCrop() 和 .fitCenter() 也都是 Transformation 所以也是遵循同时使用多个 Transformation 的规则的,即:当你使用了自定义转换后你就不能使用 .centerCrop() 或 .fitCenter() 了。这里有一个 GLide Transformations 的库,它提供了很多 Transformation 的实现,非常值得去看,不必重复造轮子对吧!
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true">
<scale
android:duration="@android:integer/config_longAnimTime"
android:fromXScale="0.1"
android:fromYScale="0.1"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1"
android:toYScale="1"/>
</set>
这是个 XML 动画缩放动画,图片刚开始小的,然后逐渐增大到原尺寸。我们现在要应用到 Glide 加载图片中去,调用 .animate() 方法传入 XML 动画的 id 即可。
Glide.with(context)
.load(mUrl)
.transform(new RoundTransformation(this , 20))
.animate( R.anim.zoom_in )
.into(mImageView);
这种加载方式用在常规的 ImageView 上是没有问题的,但如果使用的 Target 是一些自定义的时候就没法好好的实现了。这时候我们就可以通过传入实现了 ViewPropertyAnimation.Animator 接口的类对象来实现。
ViewPropertyAnimation.Animator animator = new ViewPropertyAnimation.Animator() {
@Override
public void animate(View view) {
view.setAlpha( 0f );
ObjectAnimator fadeAnim = ObjectAnimator.ofFloat( view, "alpha", 0f, 1f );
fadeAnim.setDuration( 2500 );
fadeAnim.start();
}
};
然后,我们只需要在 Glide 请求中设置这个动画对象就ok了
Glide.with(context)
.load(mUrl)
.animate( animator )
.into(viewTarget);
在 animate(View view) 中你的动画对象方法中, 你可以做任何你想要对视图做的事情。自由的用你创建的动画吧。
public class ExampleModule implements GlideModule{
@Override
public void applyOptions(Context context, GlideBuilder builder) {
// todo
}
@Override
public void registerComponents(Context context, Glide glide) {
// todo
}
}
可以看到 GlideModule 为我们提供了两个方法,这里我们主要使用的是 applyOptions(Context context, GlideBuilder builder) , 我们自己的需要重新定义的代码写在该方法里就可以了。然后我们还需要去 AndroidManifest.xml 中使用 meta 声明我们上面实现的 Module
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mrtrying.demoglide">
<application>
<meta-data
android:name="com.mrtrying.demoglide.module.ExampleModule"
android:value="GlideModule" />
...
</application>
...
</manifest>
到这里我们就完成了 ExampleModule 的声明,Glide 将会在工作是使用我们所定义的 Module
TIPS这个过程走通了,接下来我们来看看是怎么自定义的。applyOptions(Context context, GlideBuilder builder) 中有两个参数, 我们通过使用 GlideBuilder 来实现我们的需求。先看看 GlideBuilder 中可用的方法
- 我们需要将 android:name 属性改成 包名+类名 的形式,这样的引用才是正确的。如果你想删掉 Glide Module,只需要删除在 AndroidManifest.xml 中的声明就可以了。Java 类可以保存,说不定以后会用呢。如果它没有在 AndroidManifest.xml 中被引用,那它不会被加载或被使用。
- 定制 module 的话 Glide 会有这样一个优点:你可以同时声明多个 Glide module。Glide 将会(没有特定顺序)得到所有的声明 module。因为你当前不能定义顺序,请确保定制不会引起冲突!
public class QualityModule implements GlideModule{
@Override
public void applyOptions(Context context , GlideBuilder builder){
builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
}
@Override
public void registerComponents(Context context , Glide glide){
// nothing to do here
}
}
这样我们就简单的增加了 Glide 的图片质量。往往我们还会遇到一些情况,希望 Glide 可以使用我们自己的网络框架,我们就需要做一些事情来实现这个需求了。Glide 的开发者不强制设置网络库给你,所以Glide可以说和 HTTPS 无关。理论上,它可以与任何的网络库实现,只要覆盖了基本的网络能力就行。同样是需要实现 Glide 的 ModuleLoader 的接口,为了让我们更加易用,Glide 为 OkHttp 和 Volley 两个网络库提供了实现。假设我要集成 OkHttp 作为 Glide 的网络库,我可以手动实现一个 GlideModule 也可以在 build.gradle 中添加依赖:
dependencies{
//...
// Glide
compile ‘com.github.bumptech.glide:glide:3.7.0‘
// Glide‘s OkHttp Integration
compile ‘com.github.bumptech.glide:okhttp-integration:1.4.0@aar‘
compile ‘com.squareup.okhttp:okhttp:3.2.0‘
}
Gradle 会自动合并必要的 GlideModule 到你的 AndroidManifest.xml , Glide 会认可在 manifest 中存在,然后使用 OkHttp 做到的所有网络连接。
标签:使用详解 getwidth memory 顺序 要求 资源文件 设备 ges The
原文地址:https://www.cnblogs.com/Free-Thinker/p/9706688.html