Glide图片加载方案

图片加载要考虑的问题

图片加载不仅仅是将图片显示出来的问题,不同场景该使用什么缩放模式?activity销毁后图片还在后台请求?是否会造成内存浪费?设置占位符和加载失败的图片?圆角图等怎么变换?

读郭霖Glide图片加载框架总结

带着以上问题,拜读了郭霖大神的Glide图片加载框,总结并实际验证,得出以下几点:

1.图片加载周期

Glide最简单的用法:

Glide.with(context).load(url).into(imageView)

with()方法中传入的Context实例会决定Glide加载图片的生命周期,如果传入的是Activity或者Fragment的实例,那么当这个Activity或Fragment被销毁的时候,图片加载也会停止。如果传入的是ApplicationContext,那么只有当应用程序被杀掉的时候,图片加载才会停止。

想法:传入ImageView.getContext()实例是不是最好的方案,ImageView所在的Context销毁了,图片自然应该取消加载。此方案是否可行?列表的回收机制会不会有问题?

结论:不是最好的方案,fragment和adapter中ImageView.getContext()返回的都是Activity,当fragment或adapter销毁但activity并没有销毁时,图片仍会加载,所以生命周期并不合理

2.图片格式(Bitmap,Gif)

Glide是支持加载GIF图片的,不需要编写额外的代码,Glide内部会自动判断图片格式(Gif图不一定是以.gif后缀结尾的哦。

当然也可以手动指定图片格式:
调用了asBitmap()方法,静态图正常加载,GIF图无法正常播放,会在界面上显示第一帧的图片;
调用了asGif()方法,GIF图正常加载和播放,静态图加载失败。

想法:一般情况下不需要指定图片格式,动图的播放机制(一直循环播放/只播放一次)怎么设置?默认是循环播放

结论:设置监听,回调中设置播放次数,如下:

Glide.with(this)
   		.load(url)
    	.addListener(new RequestListener() {
        	@Override
        	public boolean onLoadFailed(
        	@Nullable GlideException e, Object model, 				
        	Target target, boolean isFirstResource) {
            return false;
        }

        	@Override
        	public boolean onResourceReady(Drawable resource, 
        	Object model, Target target, 
        	DataSource dataSource, 
        	boolean isFirstResource) {
            if (resource instanceof GifDrawable) {
                //设置播放次数
                ((GifDrawable) resource).setLoopCount(3);
            }
            return false;
        }
    })
    .into(iv);

缓存

在缓存这一功能上,Glide又将它分成了两个模块,一个是内存缓存,一个是硬盘缓存。
默认情况下,Glide自动就是开启内存缓存和磁盘缓存的。
磁盘缓存是存在哪的?是否需要动态权限,未授权时磁盘缓存是不是就失效了?

结论:磁盘缓存默认存储在应用内部文件,访问应用内部文件无需动态申请权限

集成网络框架

Glide默认使用的是HttpUrlConnection,支持集成Volley,Okhttp等其它网络栈。
想法:一般用的时候没有集成过网络栈,如何集成?

权限

一般使用场景是加载网络图片,Internet权限肯定是要的,但还有个小细节:如果你正在从 URL 加载图片,Glide 可以自动帮助你处理片状网络连接:它可以监听用户的连接状态并在用户重新连接到网络时重启之前失败的请求。如果 Glide 检测到你的应用拥有 ACCESS_NETWORK_STATE 权限,Glide 将自动监听连接状态而不需要额外的改动。

占位符

placeHolder
error
fallback

占位图是否会影响控件的大小?
结论:不会,网上有人说会有问题,我用的Glide4.9版本试的,可能Glide已经修复了

淡入效果

transitionOption

变换

缩放模式适配不同场景:

启动页/广告页

全屏展示(填充宽高),不变形,尽可能少的裁剪内容[我特地问了做设计的朋友,他们是有设计规范的,四周不会放内容,xx像素内是内容区域。所以适当的裁剪掉边上的内容是没有问题的]。使用centerCrop就可满足上述条件。

banner

banner一般都是以ViewPager做容器,ViewPager的高度是不支持wrap_content的,也就是说要么指定高度,要么match_parent。banner的宽一般是固定的,高度若是写死,采用fitXY在有些手机上会有变形;fitCenter周边可能会有留白;centerCrop又会裁剪掉边上的内容 (banner一般要求不能裁剪,本来区域就不大,你还裁剪,可能会丢失重要内容)。

宽固定,高根据图片比例算出控件高,设置给ViewPager,因为viewPager会预加载两边的view,所以适配的前提是所有banner图片宽高比一致(一般都能满足)

Glide.with(context)
              .load(url)
              .addListener(new RequestListener() {
                  @Override
                  public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
                      return false;
                  }

                  @Override
                  public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) {
                  //根据图片宽高比设置容器的高度
                      int intrinsicWidth = resource.getIntrinsicWidth();
                      int intrinsicHeight = resource.getIntrinsicHeight();
                      int height = intrinsicHeight * width / intrinsicWidth;
                      layoutParams.height = height;
                      return false;
                  }
              })
              .override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
              .transform(new RoundedCorners(10))
              .into(imageView);
固定宽高

图片不变形,不裁剪,fitCenter即可满足。

圆角

RoundedCorners

圆形

CircleCrop

不得不说Glide的设计真的满足了我们99%的场景需求了。

你可能感兴趣的:(Android)