在图片加载库烂大街的今天,选择一个适合自己使用的图片加载库已经成为了每一个Android开发者的必经之路。现在市面上知名的图片加载库有UIL,Picasso,Volley ImageLoader,Fresco以及我们今天的主角Glide。它们各有千秋,不能评定谁一定比谁好,只能说哪一个更适合你。


我的理解

下面我来谈一下个人对这些图片加载库的理解,如有错误,还望指教。

Universal Image Loader:一个强大的图片加载库,包含各种各样的配置,最老牌,使用也最广泛。

Picasso: Square出品,必属精品。和OKHttp搭配起来更配呦!

Volley ImageLoader:Google官方出品,可惜不能加载本地图片~

Fresco:Facebook出的,天生骄傲!不是一般的强大。

Glide:Google推荐的图片加载库,专注于流畅的滚动。

更多详情请看stackoverflow上这个问题。

初试Glide

下面进入今天的主题,相信之前很多同学都看到过这篇介绍Glide的文章,中文版在这里。文中从各个方面介绍和比较了Glide与Picasso,总体来说二者极为相似,有着近乎相同的API的使用风格。但Glide在缓存策略和加载GIF方面略胜一筹。最后作者也极力推荐了这个库。

而且据说在Google新出的Photos应用中,到处可见Glide的踪迹。看到这里,你是不是已经迫不及待的想试一试这个库呢?就在你下定决心尝试一记的时候,你又听说Yelp app(据说是美国的大众点评)也在使用这个吊炸天的库。你的心中激动万分,发四一定要使用这个库。说干就干,打开Android Studio,在builde.gradle里面添加上

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

然后全局搜索图片加载的地方,全部换成了下面的代码:

Glide.with(mContext)        .load(url)        .placeholder(R.drawable.loading_spinner)        .crossFade()        .into(myImageView);

在经过漫长的编译过程之后,再次打开APP,看到有着渐现效果的图片呈现在你的面前,你不禁叫道:“wocao,真TM帅!为什么我以前没有发现呢?”。

不过在你使用了几天之后你会发现一些问题:

为什么 有的图片第一次加载的时候只显示占位图,第二次才显示正常的图片呢?

为什么 我总会得到类似You cannot start a load for a destroyed activity这样的异常呢?

为什么 我不能给加载的图片setTag()呢?

为什么?为什么?这么NB的库竟然会有这么多的问题。没错,这就是我今天要讲的重点。怎么避免上面的问题发生。

一些解决方案

1.如果你刚好使用了这个圆形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         }     };

2.至于第二个问题,请记住一句话:不要再非主线程里面使用Glide加载图片,如果真的使用了,请把context参数换成getApplicationContext。更多的细节请参考这个issue。

3.为什么不能设置Tag,是因为你使用的姿势不对哦。如何为ImageView设置Tag呢?且听我细细道来。

方案一:使用setTag(int,object)方法设置tag,具体用法如下:

Java代码是酱紫的:

Glide.with(context).load(urls.get(i).getUrl()).fitCenter().into(imageViewHolder.image);        imageViewHolder.image.setTag(R.id.image_tag, i);        imageViewHolder.image.setOnClickListener(new View.OnClickListener() {            @Override                int position = (int) v.getTag(R.id.image_tag);                Toast.makeText(context, urls.get(position).getWho(), Toast.LENGTH_SHORT).show();            }        });

同时在values文件夹下新建ids.xml,添加

<item name="image_tag" type="id"/>

大功告成!

方案二:从Glide的3.6.0之后,新添加了全局设置的方法。具体方法如下:

先实现GlideMoudle接口,全局设置ViewTaget的tagId:

public class MyGlideMoudle implements GlideModule{    @Override    public void applyOptions(Context context, GlideBuilder builder) {        ViewTarget.setTagId(R.id.glide_tag_id);    }    @Override    public void registerComponents(Context context, Glide glide) {    }}

同样,也需要在ids.xml下添加id

<item name="glide_tag_id" type="id"/>

最后在AndroidManifest.xml文件里面添加

<meta-data    android:name="com.yourpackagename.MyGlideMoudle"    android:value="GlideModule" />

又可以愉快的玩耍了,嘻嘻`(∩_∩)′。

方案三:写一个继承自ImageViewTaget的类,复写它的get/setRequest方法。

Glide.with(context).load(urls.get(i).getUrl()).fitCenter().into(new ImageViewTarget<GlideDrawable>(imageViewHolder.image) {            @Override            protected void setResource(GlideDrawable resource) {                imageViewHolder.image.setImageDrawable(resource);            }            @Override            public void setRequest(Request request) {                imageViewHolder.image.setTag(i);                imageViewHolder.image.setTag(R.id.glide_tag_id,request);            }            @Override            public Request getRequest() {                return (Request) imageViewHolder.image.getTag(R.id.glide_tag_id);            }        });        imageViewHolder.image.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                int position = (int) v.getTag();                Toast.makeText(context, urls.get(position).getWho(), Toast.LENGTH_SHORT).show();            }        });

一些使用技巧

1.Glide.with(context).resumeRequests()和 Glide.with(context).pauseRequests()

当列表在滑动的时候,调用pauseRequests()取消请求,滑动停止时,调用resumeRequests()恢复请求。这样是不是会好些呢?

2.Glide.clear()

当你想清除掉所有的图片加载请求时,这个方法可以帮助到你。

3.ListPreloader

如果你想让列表预加载的话,不妨试一下ListPreloader这个类。

一些基于Glide的优秀库

1.glide-transformations

一个基于Glide的transformation库,拥有裁剪,着色,模糊,滤镜等多种转换效果,赞的不行不行的~~

2.GlidePalette

一个可以在Glide加载时很方便使用Palette的库。


更多相关文章

  1. 让 Android 可以识别BMP图片文件,且目前Android所支持的所有图片
  2. Android 简单热修复(上)——Java类加载器
  3. Android异步加载全解析之开篇瞎扯淡
  4. android 使用异步加载图片
  5. android 图片背景使用这种方式很爽
  6. android获得圆角图片
  7. Android在Button按钮上同时显示文字和图片
  8. android ViewFlipper实现图片轮播
  9. Android如何使用XML创建一个环形渐变颜色图片

随机推荐

  1. Android(安卓)App兼容android10.0系统需
  2. Android异步通信机制(一)
  3. android ListView自定义适配器实现
  4. Android(安卓)studio打包生成apk
  5. 使用eclipse编写并运行你的第一个Android
  6. Android(安卓)Studio中无法找到android.o
  7. android中实现“再按一次退出”功能
  8. DELPHI XE5 FOR ANDROID 模仿驾考宝典 TM
  9. Android中xml的处理
  10. Android安全防护/检查root/检查Xposed/反