今天,简单讲讲Android里Glide的简单使用。

Android框架系列:

一.android EventBus的简单使用

二.android Glide简单使用

对于Glide这个加载图片的框架,很多人都在用,我之前使用的是ImageLoader,最近查资料时,发现Glide才是Google推荐的加载图片框架,功能非常强大,而且还有Google专人维护,要知道,ImageLoader已经没人维护了,除了问题可没人解答。所以有必要整理一下Glide的使用。

Glide是谷歌为我们推荐的一个图片加载库。为什么要选择使用Glide呢?

  • 1、代码有人维护,不至于出现问题,项目组都搞不定的时候问题无法解决。(ImageLoader已没人维护了)
  • 2、代码简洁,可读性很好。(Fresco是一个非常优秀的库,但是配置稍显麻烦,同时代码风格读起来有些生疏)
  • 3、功能强大(400多k的包,包含很多功能,例如:像加载Gif图片就是Picasso做不到的)

下面我们就来介绍下Glide的用法:

Glide的基本使用

导入库

compile 'com.github.bumptech.glide:glide:3.7.0'

添加代码混淆(可加可不加)

-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {**[] $VALUES;public *;
}# for DexGuard only
-keepresourcexmlelements manifest/application/meta-data@value=GlideModule

这个别忘了,不要粗心哦,很容易忘得,最简单的问题,往往需要最简单的搞定啦。

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

简单使用例子

// For a simple view:
@Override
public void onCreate(Bundle savedInstanceState) {...ImageView imageView = (ImageView) findViewById(R.id.my_image_view);Glide.with(this).load("http://goo.gl/gEgYUd").into(imageView);
}// For a simple image list:
@Override
public View getView(int position, View recycled, ViewGroup container) {final ImageView myImageView;if (recycled == null) {myImageView = (ImageView) inflater.inflate(R.layout.my_image_view, container, false);} else {myImageView = (ImageView) recycled;}String url = myUrls.get(position);Glide.with(myFragment).load(url).centerCrop().placeholder(R.drawable.loading_spinner).crossFade().into(myImageView);return myImageView;
}

Glide使用详解

加载网络图片

Glide.with(context).load(internetUrl).into(targetImageView);

从文件加载图片

File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"Test.jpg");
Glide.with(context).load(file).into(imageViewFile);

从资源id加载图片

int resourceId = R.mipmap.ic_launcher;
Glide.with(context).load(resourceId).into(imageViewResource);

从uri加载图片

Glide.with(context).load(uri).into(imageViewUri);

播放本地mp4,只能是本地(获取MP4视频的缩略图)

String filePath = "/storage/emulated/0/Pictures/example_video.mp4";
Glide.with( context ).load( Uri.fromFile( **new **File( filePath ) ) ).into( imageViewGifAsBitmap );

加载Gif图片

String gifUrl = "xxxxx";
Glide.with( context ).load( gifUrl ).into( imageViewGif );

用bitMap播放Gif.asBitmap()

Glide.with( context ).load( gifUrl ).asBitmap().into( imageViewGifAsBitmap );

强制转化为Gif.asGif()

Glide.with( context ).load( gifUrl ).asGif().error( R.drawable.full_cake ).into( imageViewGif );

设置默认占位图.placeholder()

设置加载失败的图片.error()

Glide.with( context ).load( gifUrl ).placeholder( R.drawable.cupcake ).error( R.drawable.full_cake ).into( imageViewGif );

.fallback()

除了上面两种‘异常情况’,还有一种情形就是打开手机的通讯录的时候,可以看到你给有些喜欢的人设置了照片,然而有些可怜的人并没给有,总不能在那里留下一片空白吧,这个时候相当于传递了Null,传递null时,这个callback方法就会被调用。

Glide.with(context).load( null)//加载空指针的时候.fallback( R.drawable.wuyanzu).into( imageViewNoFade );

设置加载动画

其实这个是默认的,但是你还是可以写出来,渐显动画
1、.crossFade() :Glide提供淡如淡出

Glide.with(context).load().placeholder(R.mipmap.ic_launcher) .error(R.mipmap.future_studio_launcher).crossFade().into(imageViewFade);

这里还有一个.fadeFade(int duration),设置动画时间。如果你不想要动画可以加上.dontAnimate()
2、.animate(android.R.anim.slide_in_left):Android系统提供,从左到右滑出加载动画

调整图片大小.resize(int ,int )

单位是像素,裁剪你的图片大小。其实Glide已经会自动根据你ImageView裁剪照片来放在缓存中了。但是不想适应ImageView大小的时候,可以调用这个方法.override()为ImageView指定大小。

Glide.with(context).load(image).override(600, 200) .into(imageViewResize);

裁剪图片.fitCenter().CenterCrop()

Glide清楚在合适的ImageView中加载合适的Image.当需要裁剪大小时,有个.centerCrop方法,这个方法的裁剪会让你的ImageView周围不会留白,还有一个.fitCenter()方法,表示让你的Image完全显示,尺寸不对时,周围会留白。

设置缩略图.thumbnail()

.thumbnail()方法的目的就是让用户先看到一个低解析度的图,点开后,再加载一个高解析度的图。

//表示为原图的十分之一
Glide.with( context ).load(image).thumbnail( 0.1f ).into( imageView2 );

一种更高级的缩略图加载方式:

当缩略图也需要通过网络加载全部解析度的时候。

private void loadImageThumbnailRequest() {DrawableRequestBuilder<String> thumbnailRequest = Glide.with( context ).load( eatFoodyImages[2] );Glide.with( context ).load( UsageExampleGifAndVideos.gifUrl ).thumbnail( thumbnailRequest ).into( imageView3 );
}

设置图片显示效果(圆角、圆形、高斯模糊、蒙板、裁剪等等).bitmapTransform()

Glide.with(this).load(R.mipmap.ic_image_sample)//模糊.bitmapTransform(new BlurTransformation(this))//圆角.bitmapTransform(new RoundedCornersTransformation(this, 24, 0, RoundedCornersTransformation.CornerType.ALL))//遮盖.bitmapTransform(new MaskTransformation(this, R.mipmap.ic_launcher))//灰度.bitmapTransform(new GrayscaleTransformation(this))//圆形.bitmapTransform(new CropCircleTransformation(this)).into(mResultIv);

除此之外还有实现诸如马赛克、明暗度等更多滤镜处理:

  • ToonFilterTransformation
  • SepiaFilterTransformation
  • ContrastFilterTransformation
  • InvertFilterTransformation
  • PixelationFilterTransformation
  • SketchFilterTransformation
  • SwirlFilterTransformation
  • BrightnessFilterTransformation
  • KuwaharaFilterTransformation
  • VignetteFilterTransformation

Glide的缓存

用过手机的都知道,当划上划下一个ListView的时候,第二次都比第一次快,就是因为为GlideView对资源进行了缓存,而且封装的很好,甚至不需要自己去设定缓存大小,Glide会智能地自己给我们根据设备设置缓存大小。

缓存是为了减少或者杜绝多的网络请求。为了避免缓存,Glide用了内存缓存和‘外存缓存机制’,并且 提供了相应的方法,完全封装,不需要处理细节。Glide会自动缓存到内存,除非调用.skipMemoryCache( true )。尽管调用了这个,Glide还是会缓存到外存,还有一种情形,就是有一张图片,但是这张图变化非常快,这个时候可能并不想缓存到外存中,就使用.diskCacheStrategy( DiskCacheStrategy.NONE )。如果你两种都不需要,可以两个方法组合着一起使用。

自定义外存缓存机制

Glide默认会缓存Image的很多个版本,比如原图,如果你的imageView大小的缓存。.diskCacheStrategy()有以下几种缓存策略:

  • DiskCacheStrategy.NONE 什么都不缓存
  • DiskCacheStrategy.SOURCE 只缓存最高解析图的image
  • DiskCacheStrategy.RESULT 缓存最后一次那个image,比如有可能你对image做了转化
  • DiskCacheStrategy.ALL image的所有版本都会缓存
Glide.with( context ).load( image ).diskCacheStrategy( DiskCacheStrategy.SOURCE ).into( imageViewFile );

修改缓存大小、位置、加载图片质量

和指定HttpClent为OkHttp一样,只不过我们需要配置一些信息在applyOptions()函数里面

public class GlideConfigModule implements GlideModule {@Overridepublic void applyOptions(Context context, GlideBuilder builder) {// 指定位置在packageName/cache/glide_cache,大小为MAX_CACHE_DISK_SIZE的磁盘缓存builder.setDiskCache(new InternalCacheDiskCacheFactory(context, "glide_cache", ConfigConstants.MAX_CACHE_DISK_SIZE));//指定内存缓存大小builder.setMemoryCache(new LruResourceCache(ConfigConstants.MAX_CACHE_MEMORY_SIZE));//全部的内存缓存用来作为图片缓存builder.setBitmapPool(new LruBitmapPool(ConfigConstants.MAX_CACHE_MEMORY_SIZE));builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);//和Picasso配置一样}@Overridepublic void registerComponents(Context context, Glide glide) {}
}
 <meta-data            android:name="com.example.imageloadpk.adapter.config.GlideConfigModule"android:value="GlideModule"/>

一般的图片加载框架设置了磁盘缓存和内存缓存就行了,但是Glide还设置了一个图片缓存。
图片缓存 <= 内存缓存

builder.setDiskCache(new InternalCacheDiskCacheFactory(context, "glide_cache", ConfigConstants.MAX_CACHE_DISK_SIZE));//指定内存缓存大小builder.setMemoryCache(new LruResourceCache(ConfigConstants.MAX_CACHE_MEMORY_SIZE));//全部的内存缓存用来作为图片缓存builder.setBitmapPool(new LruBitmapPool(ConfigConstants.MAX_CACHE_MEMORY_SIZE));

这里Glide不仅可以缓存图片,还可以缓存其他文件譬如视频之类,也就是说可以把他作为我们的缓存工具来使用,当然缓存方式还是使用LRU。这样我们就不必再去重新集成LruCache和DiskLruCache,再去申请空间,配置。直接可以复用Glide的。

使用缓存也加载动画

但是,动画默认是在图片没有缓存的情况下才加载,想想也是合理的,如果图片已近下载到本地加载速度将会非常快,这个时候使用动画过渡反而碍事。要让从缓存中图片呈现也加载动画不能通过这种方式实现,可以用监听器来做。

   private RequestListener<String, GlideBitmapDrawable> mAnimationRequestListener = new RequestListener<String, GlideBitmapDrawable>() {@Overridepublic boolean onException(Exception e, String model, Target<GlideBitmapDrawable> target, boolean isFirstResource) {return false;}@Overridepublic boolean onResourceReady(GlideBitmapDrawable resource, String model, Target<GlideBitmapDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {dissProgress();if (isFromMemoryCache) {//如果是从缓存加载,设置动画效果mIvShow.setAnimation(AnimationUtils.loadAnimation(mContext, R.anim.scale));}//返回true表示拦截不再传递,false表示事件会传递下去return false;}};

请求优先级.priority()

加载图片肯定也是有先后顺序,Glide提供了.priority()这个方法,它接收以下几个参数:

  • Priority.LOW
  • Priority.NORMAL
  • Priority.HIGH
  • Priority.IMMEDIATE

但是Glide并不一定会按照你的顺序来,只是尽量按照你的顺序来。(比如给一张很大的图片最高的优先权,但是它并不一定比低优先级的图先加载出来,这个时候只有使用缩略图了)

Glide.with(mContext).load(Url.IMAGE_URL_TROCHILIDAE).priority(Priority.HIGH).into(mIvTonyRight);

利用callback在非标准情况下加载图片

上面所有的情况都是加载图片到ImageView中,但是并不是所有的情况都是这样。譬如加载的控件类型不是ImageView,是个自定义的布局。或者加载为Background的形式。
可以使用SimpleTarget类型,这里指定他的大小为500*100,加载为背景图片

.into(new SimpleTarget<Drawable>(500, 100) {@Overridepublic void onResourceReady(Drawable resource, GlideAnimation<? super Drawable> glideAnimation) {mBtnClear.setBackground(resource);}

同理下载图片原理是一样

.into(new SimpleTarget<Bitmap>() {@Overridepublic void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {//toSaveLog.d(TAG, "onResourceReady: save successful");}
});

Glide中的回调:Targets

从上面的介绍,已经可以看出Glide内部封装了所有的细节,什么网络请求,什么缓存机制,当所有都就绪过后,自动切换回UI线程,更新ImageView。Targets就是Glide中的回调,当异步线程中所有的工作做完过后返回结果。说白了就是,当请求图片完成后,需要回调的方法。

SimpleTarget

private SimpleTarget target = new SimpleTarget<Bitmap>() {@Overridepublic void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) {// do something with the bitmap// for demonstration purposes, let's just set it to an ImageViewimageView1.setImageBitmap( bitmap );}
};private void loadImageSimpleTarget() {Glide.with( context ) *// could be an issue!*.load( eatFoodyImages[0] ).asBitmap()//强制Glide返回一个Bitmap.into( target );
}

注意事项:

1、上面这段代码不要写成匿名内部类的机制,原因就是java的自动垃圾回收机制可能在图片还没有加载好的时候就已经把你的Target回收了。

2、注意.with()里面的参数,Glide的请求是和传进去的Context共存亡的,如果传一个Activity进去,当Activity GC过后,你的请求也就GC了,但是如果这样传:.with(context.getApplicationContext() ).当你的Activity GC过后,请求还是会继续,回调还是会继续。
有size的Target

如果传给into().的是一个ImageView,但是图片的size比ImageView的Size打,Glide为了节省时间,会加载小的那个size的Image。但是这对Target并不适用,以为这里并不知道SIze。但是如果知道image应该多大,可以传递给Target.就像下面这样:

private SimpleTarget target2 = new SimpleTarget<Bitmap>( 250, 250 ) {@Overridepublic void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) {imageView2.setImageBitmap( bitmap );}
};private void loadImageSimpleTargetApplicationContext() {Glide.with(context.getApplicationContext()); *// safer!*.load( eatFoodyImages[1] ).asBitmap().into( target2 );
}

ViewTarget

适用于想Glide加载到自定义View中去,

public class FutureStudioView extends FrameLayout {ImageView iv;TextView tv;public void nitialize(Context context) {inflate( context, R.layout.custom_view_futurestudio, this );iv = (ImageView) findViewById( R.id.custom_view_image );tv = (TextView) findViewById( R.id.custom_view_text );}public FutureStudioView(Context context, AttributeSet attrs) {super( context, attrs );initialize( context );}public FutureStudioView(Context context,AttributeSet attrs,int defStyleAttr) {super( context, attrs, defStyleAttr );initialize( context );}public void setImage(Drawable drawable) {iv = (ImageView) findViewById( R.id.custom_view_image );iv.setImageDrawable( drawable );}
}

还有notificationTarget 和AppWidget作为扩展自行研究喽。

监听器配置.listener()

Glide.with(getContext()).load(url).listener(mRequestListener)//配置监听器.placeholder(Drawables.sPlaceholderDrawable).error(Drawables.sErrorDrawable).into(mImageView);private RequestListener<String, GlideDrawable> mRequestListener = new RequestListener<String, GlideDrawable>() {@Overridepublic boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {//显示错误信息Log.w(TAG, "onException: ", e);//打印请求URLLog.d(TAG, "onException: " + model);//打印请求是否还在进行Log.d(TAG, "onException: " + target.getRequest().isRunning());return false;}@Overridepublic boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {return false;}};

这里的onException捕获异常,如果返回true表示我们自己处理掉了异常,false表示交给Glide去处理,因为我们定义了.error()那么就显示error里面的内容。

这里onResourceReady表示是否准备资源显示,返回true表示用户自己已经设置好资源,包括截取操作,动画操作之类的,准备好显示。false表示交给Glide

如此修改后,就能够看到图片加载日志了,方便我们调试

替换掉自带的HttpClient

只需两步
Step1:
导入需要替换的HttpClient,可以选择Volley也可以选择OkHttp,我们使用Okhttp,在Module的build.gradle文件中配置

dependencies {compile 'com.github.bumptech.glide:okhttp3-integration:1.4.0@aar'compile 'com.squareup.okhttp3:okhttp:3.3.1'orcompile 'com.github.bumptech.glide:volley-integration:1.4.0@aar'compile 'com.mcxiaoke.volley:library:1.0.8'
}

这个版本具体选择多少,可以在https://github.com/bumptech/glide/wiki/Integration-Libraries这里查询到
Step2:
在AndroidMainfest.xml文件中写入

这个版本具体选择多少,可以在https://github.com/bumptech/glide/wiki/Integration-Libraries这里查询到
Step2:
在AndroidMainfest.xml文件中写入

 <meta-data         android:name="com.bumptech.glide.integration.okhttp3.OkHttpGlideModule"android:value="GlideModule"/>

你可能会有和我一样的疑问,Glide可以通过在配置清单里面配置
能不能写几个meta-data标签,一个标签里面配置一点参数
经过测试,发现这样做也是可以的。但是如果是同一种配置信息,比如你集成了OkHttp,又写一个标签集成Volley,最后一个会把前面的覆盖掉。

注意事项

1、前面我们已经学习到asGif()可以加载gif图,asBitmap()可以加载静态gif图即gif图的第一帧,如果非gif图用asGif()方法加载呢?这时候会报错。。Glide默认可以自动识别图片格式,加载gif图,所以在不确定图片格式的情况下,不要直接写asGif哦。

2、You cannot start a load for a destroyed activity这样的异常如何处理?
记住不要再非主线程里面使用Glide加载图片,如果真的使用了,请把context参数换成getApplicationContext。希望可以帮你避免这个问题。

3、为什么有的图片第一次加载的时候只显示占位图,第二次才显示正常的图片呢?
.如果你刚好使用了这个圆形Imageview库或者其他的一些自定义的圆形Imageview,而你又刚好设置了占位的话,那么,你就会遇到第一个问题。如何解决呢?

方案一: 不设置占位;
方案二:使用Glide的Transformation API自定义圆形Bitmap的转换。这里是一个已有的例子;
方案三:使用下面的代码加载图片:

Glide.with(mContext).load(url) .placeholder(R.drawable.loading_spinner).into(new SimpleTarget<Bitmap>(width, height) {@Override public void onResourceReady(Bitmap bitmap, GlideAnimation anim) {// setImageBitmap(bitmap) on CircleImageView } };

4、图片大小拉伸问题
有时候你会发现网络加载完了之后会有拉伸现象,而你的控件大小明明是自适应的呀,这是为什么呢,请你检查下你是否设置了占位图,有的话请去掉就ok了。

简单总结一下,我这里讲了Glide比较全面的用法,有如何加载图片,Glide的缓冲设置,Glide设置圆角,Glide设置图片的background,Glide加载GIF图片等,大家使用的话一般了解加载图片和圆角图片就可以了。这里在列举一下。

 //圆形裁剪Glide.with(this).load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png").bitmapTransform(new CropCircleTransformation(this)).into(iv_0);//圆角处理Glide.with(this).load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png").bitmapTransform(new RoundedCornersTransformation(this,30,0, RoundedCornersTransformation.CornerType.ALL)).into(iv_0);

android Glide简单使用就讲完了。

就这么简单。

android Glide简单使用相关推荐

  1. Android Glide加载图片成圆形

    今天,简单讲解android使用glide加载图片成圆形. 这个很简单,因为之前需要在RecyclerView里加载圆形图片,所以在网上查找了资料,很简单就解决了. 1.导入依赖 implementa ...

  2. Android Glide图片加载框架(三)缓存机制

    文章目录 一.缓存简介 二.缓存用法 内存缓存方式 磁盘缓存方式 三.缓存KEY 四.内存缓存 内存缓存流程 五.磁盘缓存 磁盘缓存流程 Android Glide图片加载框架系列文章 Android ...

  3. Android Glide图片加载框架(二)源码解析之into()

    文章目录 一.前言 二.源码解析 1.into(ImageView) 2.GlideContext.buildImageViewTarget() 3.RequestBuilder.into(Targe ...

  4. Android Glide图片加载框架(二)源码解析之load()

    文章目录 一.前言 二.源码分析 1.load() Android Glide图片加载框架系列文章 Android Glide图片加载框架(一)基本用法 Android Glide图片加载框架(二)源 ...

  5. Android Glide图片加载框架(二)源码解析之with()

    文章目录 一.前言 二.如何阅读源码 三.源码解析 1.with() Android Glide图片加载框架系列文章 Android Glide图片加载框架(一)基本用法 Android Glide图 ...

  6. Android Glide图片加载框架(一)基本用法

    文章目录 一.前言 二.简介 三.基本用法 第一步:调用 Glide.with() 方法创建加载图片的实例 第二步:调用 load() 方法指定待加载的图片资源 第三步:调用 into() 方法绑定显 ...

  7. android glide圆形图片,Android Glide加载图片成圆形

    释放双眼,带上耳机,听听看~! 今天,简单讲解android使用glide加载图片成圆形. 这个很简单,因为之前需要在RecyclerView里加载圆形图片,所以在网上查找了资料,很简单就解决了. 1 ...

  8. Android Glide 升级4.8 后, 原方法 animate() 无法使用

    转载声明:本文来自 https://blog.csdn.net/shijianduan1/article/details/86675168 其他链接:Android Glide 升级4.8 后, 原方 ...

  9. Android Glide 3.7.0 源码解析(八) , RecyclableBufferedInputStream 的 mark/reset 实现

    个人博客传送门 一.mark / reset 的作用 Android Glide 3.7.0 源码解析(七) , 细说图形变换和解码有提到过RecyclableBufferedInputStream ...

最新文章

  1. Linux zip-tar.gz 压缩解压
  2. 数据仓库与联机分析处理
  3. haproxy调度web案例
  4. 职场中一路走来却拂不去一丝失落——一个女IT的告白
  5. Linux之命令行快捷键(记住的我没写)
  6. linux主机数据拷贝,linux 服务器之间拷贝文件
  7. LeetCode-76: 最小覆盖子串
  8. 判断鼠标向右或向左滑动,响应不同的事件
  9. 电大考的是职称英语同计算机,最新电大统考计算机应用基础真题选择题详细分析小抄.doc...
  10. 【语音识别】基于matlab矢量量化(VQ)说话人识别【含Matlab源码 575期】
  11. 小程序云开发——列表页和详情页
  12. 怎么隐藏鼠标箭头_立刻上手,无鼠标高效操作excel指南(一)
  13. RK3568平台开发系列讲解(蓝牙篇)蓝牙通讯协议PhoneBookAccessProfile(PBAP)同步通讯录
  14. yaml 编码格式简述
  15. 增量爬取电影网站2级详情页面电影名称和下载链接
  16. 印象笔记Markdown思维导图
  17. Vue-idea的搭建
  18. Redmibook16锐龙版蓝屏自动重启
  19. 互联网加比赛“潜规则”,你知道多少?干货满满,说一说亲身经历
  20. base64转cer_常见证书格式及相互转换

热门文章

  1. 改进 网站资源探测工具(添加代理)
  2. UVaLive 7361(矩阵快速幂)
  3. UITableView性能优化与卡顿
  4. Android TextView 手动上下滑动
  5. HashMap和Hashtable的区别 2
  6. 大数据生态及其技术栈
  7. jdk动态代理源码分析(一)---代理的定义
  8. 第一次刷Leetcode,为什么耗费很多时间
  9. memcache调整value大小限制
  10. Xcode8打包上传后构建版本消失问题