Glide v4

作者: whstywh | 来源:发表于2017-02-06 10:35 被阅读0次
    Photo by Jakob Owens on Unsplash

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

    • GlideV4中如centerCrop()placeholder()等方法已经不能直接通过流式API的方式调用;
      如果还是想通过V3版本的方式调用,官方也提供了一种解决方案:

    • 添加依赖

    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的用法;

    • RequestOptions
      Glide中的大多数设置都可以使用RequestOptions类和apply()方法来应用;
            /**
             * 磁盘缓存策略: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) {
        }
    }
    

    • TransitionOptions
      有三种:
      GenericTransitionOptions
      DrawableTransitionOptions
      BitmapTransitionOptions

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

           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
            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和Picasso的区别

    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的方式则因为需要在显示之前重新调整大小而导致有一些延迟。

    相关文章

      网友评论

          本文标题:Glide v4

          本文链接:https://www.haomeiwen.com/subject/ntyjittx.html