Glide v4

2017-02-06  本文已影响0人  whstywh
Photo by Jakob Owens on Unsplash

学习于:https://bumptech.github.io/glide/
http://blog.csdn.net/u013005791/article/details/74532091

repositories {
  mavenCentral()
}

dependencies {
    compile 'com.github.bumptech.glide:glide:4.0.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.0.0'
    compile 'com.android.support:support-v4:25.3.1'
}

并且创建一个AppGlideModule的实现类,之后Rebuild工程,然后就能找到GlideApp对象了,然后就可以和Glide v3一样使用了;

AppGlideModule如果注释不存在,则不会发现该模块,并且您将在日志中看到一条带有Glide日志标记的警告,该日志标记指示该模块无法找到。


接下来将在V4基础上重新学习Glide的用法;

        /**
         * 磁盘缓存策略:diskCacheStrategy(DiskCacheStrategy.NONE)
         *
         * DiskCacheStrategy.ALL 使用DATA和RESOURCE缓存远程数据,仅使用RESOURCE来缓存本地数据。
         * DiskCacheStrategy.NONE 不使用磁盘缓存
         * DiskCacheStrategy.DATA 在资源解码前就将原始数据写入磁盘缓存
         * DiskCacheStrategy.RESOURCE 在资源解码后将数据写入磁盘缓存,即经过缩放等转换后的图片资源。
         * DiskCacheStrategy.AUTOMATIC 根据原始图片数据和资源编码策略来自动选择磁盘缓存策略。
         */

        /**
         * 优先级:priority(Priority.HIGH)
         * 
         * Priority.LOW 
         * Priority.NORMAL 
         * Priority.HIGH 
         * Priority.IMMEDIATE
         */

        RequestOptions options = new RequestOptions()
                .placeholder(R.mipmap.ic_launcher)
                .error(R.mipmap.ic_launcher)
                .fallback(R.mipmap.ic_launcher)
                .diskCacheStrategy(DiskCacheStrategy.NONE)
                .priority(Priority.HIGH)
                .override(800,800)
                .circleCrop();
//                .transform(new GlideRoundTransform (context))
//                .centerInside();
//                .centerCrop();


        Glide.with(this)
                .load(R.mipmap.gifpic)
                .apply(options)
                .into(imageView);

**清除缓存**:
//清理磁盘缓存 需要在子线程中执行
 Glide.get(this).clearDiskCache();
//清理内存缓存 可以在UI主线程中进行
 Glide.get(this).clearMemory();

apply:应用ResquestOptions对象,该方法可以调用多次,但是如果两次apply存在冲突的设置,会以最后一次为准;

placeholder(占位符):当请求成功完成时,占位符将被替换为请求的资源。如果从内存中加载所请求的资源,则占位符可能永远不会显示。如果请求失败,并且未设置error(),占位符将继续显示。类似地,如果所请求的url / model是null并且既不设置error()也不是fallback(),则占位符也将继续显示;
占位符是从Android资源在主线程上加载的,所以尽可能是小的容易缓存的资源;
error:当请求永久失败时显示。如果所请求的url / model是null并且没有设置fallback(),则也显示;
fallback:当请求的url / model是null的时候,显示fallback()设置的资源;

CenterCrop:缩放宽和高都到达View的边界,有一个参数在边界上,另一个参数可能在边界上,也可能超过边界;
CenterInside :如果宽和高都在View的边界内,那就不缩放,否则缩放宽和高都进入View的边界,有一个参数在边界上,另一个参数可能在边界上,也可能在边界内;
CircleCrop :圆形且结合了CenterCrop的特性;
FitCenter:缩放宽和高都进入View的边界,有一个参数在边界上,另一个参数可能在边界上,也可能在边界内;
但是其实完全可以在layout文件中设置ImageView为android:scaleType="centerCrop",Glide会自动根据这个属性设置图片的显示方式;

overrid:Glide 会根据ImageView的大小,自动限制图片缓存和内存中的大小,同时也可以调用override(width, height)限制图片的大小;

transform:自定义GlideRoundTransform类实现圆角图片;

/**
 * Created by whstywh on 2017/4/5
 * GitHub:https://github.com/whstywh
 * email:whstywh@gmail.com
 * description:自定义Glide圆角图片类
 */

public class GlideRoundTransform extends BitmapTransformation {

    public GlideRoundTransform(Context context) {
        super(context);
    }

    /**
     * 重写 生成圆角图片
     *
     * @param pool
     * @param toTransform
     * @param outWidth
     * @param outHeight
     * @return
     */
    @Override
    protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) {
        return circleCrop(pool, toTransform);
    }

    private static Bitmap circleCrop(BitmapPool pool, Bitmap source) {
        if (source == null) return null;

        int size = Math.min(source.getWidth(), source.getHeight());
        int x = (source.getWidth() - size) / 2;
        int y = (source.getHeight() - size) / 2;

        Bitmap squared = Bitmap.createBitmap(source, x, y, size, size);

        Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888);
        if (result == null) {
            result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
        }

        Canvas canvas = new Canvas(result);
        Paint paint = new Paint();
        //画布中背景图片与绘制图片交集部分
        paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
        paint.setAntiAlias(true);
        float r = size / 2f;
        canvas.drawCircle(r, r, r, paint);
        return result;
    }

    @Override
    public void updateDiskCacheKey(MessageDigest messageDigest) {
    }
}

为避免突然变化,您可以在图像切换时设置淡入淡出;

       Glide.with(this)
               .load(R.mipmap.gifpic)
               .apply(options)
               .transition(DrawableTransitionOptions.withCrossFade())
//                .transition(BitmapTransitionOptions.withCrossFade())
//                .transition(GenericTransitionOptions.with())
               .into(imageView);

TransitionOptions并且与Glide要加载的资源类型相关;
因此,如果你要求Drawable,则需要使用交叉淡入浅出DrawableTransitionOptions.withCrossFade(),如果您要求Bitmap,则需要使用简单的淡入淡出BitmapTransitionOptions.withCrossFade();如果既不是Bitmap也不是Drawable可以使用GenericTransitionOptions

如果要使用自定义的动画,可以使用GenericTransitionOptions.with(int viewAnimationId)或者BitmapTransitionOptions.withCrossFade(int animationId, int duration)或者DrawableTransitionOptions.withCrossFade(int animationId, int duration)

出于性能考虑,最好不要在ListView,GridView,RecycleView中使用过渡动画,可以使用.dontAnimate()不加载动画:

        RequestOptions options = new RequestOptions()
                ...
                .dontAnimate()
        RequestBuilder<Drawable> requestBuilder = Glide.with(this)
                .asGif()
//                .asBitmap()
//                .asDrawable()
//                .asFile()
                .load(R.mipmap.gifpic);

        requestBuilder.thumbnail(0.1f)
                .listener(new RequestListener<Drawable>() {
                    @Override
                    public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                        Log.d("flag", "onLoadFailed");
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                        Log.d("flag", "onResourceReady");
                        return false;
                    }
                })
                .apply(options)
                .transition()
                .into(imageView);

with:方法相比Picasso而言不仅接受Context,还接受Activity,Fragment,View;


加载GIF
如果使用了.asGif()方法,图片会强制转换成gif图,此时传入的图片就必须是gif图,否则会报错。当然不使用.asGif()方法同样也可以加载gif图;
load:方法中可以传入联网请求的url,资源id,File;相比Picasso还支持GIF图,本地MP4播放;

thumbnail:设置缩略图,传入一个(0,1)之间的float数值时,表示缩略图为原图的十分之几,如果缩略图比全尺寸图先加载完,就显示缩略图,否则就不显示;如果缩略图也来自网络获取时,代码如下:
        requestBuilder.thumbnail(Glide.with(this).load(thumbnailUrl))
                 ...
                .into(imageView);

listener:监听资源加载的请求状态,可以使用两个回调:onResourceReadyonLoadFailed,但不要每次请求都使用新的监听器,要避免不必要的内存申请,可以使用单例进行统一的异常监听和处理。
apply:应用RequestOptions
transition:应用TransitionOption


Recycle的加载优化
只在拖动和静止时加载,自动滑动时不加载。

        recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                switch (newState) {
                    case RecyclerView.SCROLL_STATE_DRAGGING:
                        Glide.with(MainActivity.this).resumeRequests();//加载
                        break;
                    case RecyclerView.SCROLL_STATE_SETTLING:
                        Glide.with(MainActivity.this).pauseRequests();//暂停加载
                        break;
                    case RecyclerView.SCROLL_STATE_IDLE:
                        Glide.with(MainActivity.this).resumeRequests();//加载
                        break;
                }
            }
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
            }
        });

Glide默认的Bitmap格式是RGB_565 ,比 Picasso的ARGB_8888格式的内存开销要小一半。

Picasso是加载了全尺寸的图片到内存,然后让GPU来实时重绘大小。而Glide加载的大小和ImageView的大小是一致的,因此内存花销更小。

Picasso和Glide在磁盘缓存策略上有很大的不同。Picasso缓存的是全尺寸的,而Glide缓存的是跟ImageView尺寸相同的。

尝试将ImageView调整成不同大小,但不管大小如何Picasso只缓存一个全尺寸的。Glide则不同,它会为每种大小的ImageView缓存一次。尽管一张图片已经缓存了一次,但是假如你要在另外一个地方再次以不同尺寸显示,则需要重新下载,调整成新尺寸的大小,然后将这个尺寸的也缓存起来。

另外Glide也可以既缓存全尺寸又缓存其他尺寸:

Glide.with(this)  
     .load(url)  
     .diskCacheStrategy(DiskCacheStrategy.ALL)  
     .into(imageView); 

Glide的优点是加载显示非常快。而Picasso的方式则因为需要在显示之前重新调整大小而导致有一些延迟。

上一篇下一篇

猜你喜欢

热点阅读