配置介绍
- 测试机 genymotion dpi:320
- Glide 版本3.7.0
- ImageView大小100dp*100dp 即(200px*200px)
- 预备知识 一般认为一张图片在android中的byte=像素总数*4(默认Glide采用的是Bitmap.Config.RGB_565(DecodeFormat.PREFER_RGB_565).也就是两个字节表示一个像素)
- 网络图片地址:http://b.hiphotos.baidu.com/image/pic/item/d009b3de9c82d15825ffd75c840a19d8bd3e42da.jpg
- 网络图片尺寸:768px*1152px
- Gif地址 http://img.huachitour.com/top/uploads/allimg/20151201/143306_34159.gif
基础加载
加载网络图片(网络地址)
Glide.with(context).load(netUrl).into(iv);
加载res资源(资源id)
Glide.with(context).load(R.mipmap.mv).into(iv);
加载文件
File imageFile=new File(Environment.getExternalStorageDirectory(),"mv.jpg"); Glide.with(context).load(imageFile).into(iv);
加载Uri
File imageFile=new File(Environment.getExternalStorageDirectory(),"mv.jpg"); Uri imageUri = Uri.fromFile(imageFile); Glide.with(context).load(imageUri).into(iv);
占位图片
Glide.with(context).load(R.mipmap.mv).placeholder(R.mipmap.ic_launcher).into(iv);
错误图片
int imageResId=100; Glide.with(context).load(imageResId).error(R.mipmap.ic_launcher).into(iv);
通知栏图片加载
通知代码
private void showNotifaction() { NotificationCompat.Builder builder = new NotificationCompat.Builder(this); builder.setSmallIcon(R.mipmap.ic_launcher); remoteViews = new RemoteViews(getPackageName(), R.layout.layout_notification); builder.setContent(remoteViews); notification = builder.build(); nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); nm.notify(1, notification); }
NotificationTarget代码(也可以使用Glide自带的NotificationTarget)
class NotificationTarget extends SimpleTarget<GlideDrawable> { RemoteViews remoteViews; int notificationId; Notification notification; public NotificationTarget(RemoteViews remoteViews, int notificationId, Notification notification) { this.notification = notification; this.notificationId = notificationId; this.remoteViews = remoteViews; } @Override public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) { // 设置 drawable的尺寸 draw绘制的时候 生效 resource.setBounds(0,0,resource.getIntrinsicWidth(),resource.getIntrinsicHeight()); Bitmap bitmap = Bitmap.createBitmap(resource.getIntrinsicWidth(), resource.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); resource.draw(canvas); iv.setImageBitmap(bitmap); remoteViews.setImageViewBitmap(R.id.notification_iv, bitmap); notification.contentView = remoteViews; nm.notify(notificationId, notification); } }
更新代码
Glide.with(context).load(netUrl).into(new NotificationTarget(remoteViews, 1, notification));
加载gift
Glide.with(context).load(gifUrl).into(iv); // 3.7.0 可以自动识别是否是gif // 保险起见可以这样写 Glide.with(context).load(gifUrl).asGif().into(iv); // 想加载静图可以这样 Glide.with(context).load(gifUrl).asBitmap().into(iv);
磁盘缓存
- Glide默认开启三级缓存(内存/磁盘/网络)
- 磁盘缓存策略DiskCacheStrategy
- DiskCacheStrategy.NONE(转换之后的和原始的都不存储)
- DiskCacheStrategy.SOURCE 只存储原始的
- DiskCacheStrategy.RESULT 转换之后的
- DiskCacheStrategy.ALL 两者都存储
- 默认的磁盘存储策略是 DiskCacheStrategy.RESULT
- 注意:这里说的缓存策略指的是同一个url的。也就是需要第一次加载的时候设置好磁盘缓存策略。如果第一次和第二次设置的策略不同。以第一次为准。
- 一般对于经常改变的图片,我们需要第一次加载的时候就设置策略为 DiskCacheStrategy.NONE。
- 如果我们在其他很多地方需要对图片进行不同的转换,一般我们设置策略为 DiskCacheStrategy.SOURCE
系统默认的缓存路径是/data/data/packagename/cache/,如果我们想修改目录,调用下面代码
static { // 只能调用一次 Glide.setup(new GlideBuilder(context).setDiskCache(new DiskLruCacheFactory("/sdcard/",1024*1024*10))); }
内存缓存 ###
设置Lrucache缓存大小
Glide.setup(new GlideBuilder(context).setMemoryCache(new LruResourceCache((int) (Runtime.getRuntime().maxMemory()/8)));
禁止内存缓存
Glide.with(context).load(netUrl).skipMemoryCache(true).into(iv);
对于经常改变的图片,我们一般需要禁止磁盘缓存和内存缓存
// 一定要在第一次加载这个url的图片的时候设置,否则如果已经缓存,则这么设置也就没有用了 Glide.with(context).load(netUrl).skipMemoryCache(true).diskCacheStrategy(DiskCacheStrategy.NONE).into(iv);
下载图片
获得下载图片的文件,注意需要运行在子线程中
FutureTarget<File> fileFutureTarget = Glide.with(context).load(netUrl).downloadOnly(100, 100); File file = fileFutureTarget.get();
获得GlideDrawable对象
FutureTarget<GlideDrawable> into = Glide.with(context).load(netUrl).into(100, 100);
也可以使用SimpleTarget
Glide.with(context).load(netUrl).asBitmap().into(new SimpleTarget<Bitmap>() { @Override public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) { } });
压缩
默认压缩效果
- Glide默认会根据我们的ImageView的大小来压缩图片的。默认的 DiskCacheStrategy.RESULT 一般也认为缓存的是压缩之后的图片。
验证
Glide.with(context).load(netUrl).asBitmap().into(new SimpleTarget<Bitmap>() { @Override public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) { Log.e("tag",resource.getByteCount()+"");//1769472 字节 } });
1769472=768px*1152px*2(2个字节)因为Glide的Config.RGB_565.因此对应下来了
那么通过方法获得的pixs是多少呢?
// 异步执行 Glide.with(context).load(netUrl).centerCrop().into(iv); // 同步执行 // 之所以drawable不为null,是因为有内存缓存,磁盘缓存和网络缓存读取都是异步的 Drawable drawable = iv.getDrawable(); if (drawable != null) { int pixs = drawable.getIntrinsicWidth() * drawable.getIntrinsicHeight(); Log.e("tag", pixs + "");// 打印出来是40000 }
- 40000=200px*200px 也就是image的大小。因此验证了,默认Glide加载显示到ImageView的时候,已经根据ImageView的大小压缩了。
- 注意使用centerCrop()和fitCenter()获得的大小不一致.因为图片的压缩不一样。
- centerCrop一定会填充满ImageView。但是会裁剪。
- fitCenter不会裁剪,但是可能填充不满ImageView。
- Glide默认使用的是fitCenter()。也就是ImageView获得的bitmap一般会比centerCrop()要小。
也可通过下面方法验证bitmap的大小和ImageView的大小关系,以及默认使用的Config.RGB_565
new Thread(){ @Override public void run() { FutureTarget<Bitmap> into = Glide.with(context).load(netUrl).asBitmap().into(200, 200); if(into!=null){ Bitmap bitmap = null; try { bitmap = into.get(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } Log.e("tag",bitmap.getByteCount()+"");// 442368 Log.e("tag",bitmap.getWidth()+"");// 284 Log.e("tag",bitmap.getHeight()+"");// 576 Log.e("tag",(bitmap.getConfig()== Bitmap.Config.RGB_565)+"");// true Log.e("tag",bitmap.getByteCount()/(bitmap.getWidth()*bitmap.getHeight())+"");//2 } } }.start();
可能有人会问,为什么into要比直接加载到ImageView还要大些?因为直接加载使用了centerCrop(),这样又缩小了一部分。这里提示下默认图片的大小是(768px*1152px)
也可以调用下面方法,来压缩。下面方法一般用于不知道view的大小。
Glide.with(context).load(netUrl).override(200,200).into(iv);。
缩略图
Glide.with(context).load(netUrl).thumbnail(0.1f).into(iv);
加载优先级
对于一些影响用户体验的图片我们可以提高加载的优先级,让其尽量提前显示
//优先级由高到低 public enum Priority { IMMEDIATE, HIGH, NORMAL, LOW, priority, } Glide.with(context).load(netUrl).priority(Priority.IMMEDIATE).into(iv); Glide.with(context).load(netUrl).priority(Priority.HIGH).into(iv); Glide.with(context).load(netUrl).priority(Priority.NORMAL).into(iv); Glide.with(context).load(netUrl).priority(Priority.LOW).into(iv);
为了提高列表控件性能,我们可以在抛动的时候暂停加载,在停止的时候重新开始加载
// 恢复没有加载完的 Glide.with(context).resumeRequests(); // 暂停没有加载完的 Glide.with(context).pauseRequests();
预加载,当我们知道未来一段时间我们会操作某张图片的时候,我们可以预加载
Glide.with(context).load(netUrl).preload();
Glide加载和生命周期回调
Glide.with(activity);// 和Activity的生命周期关联。在onStart的时候开始加载,在onStop的时候暂停加载。在onDestory的时候清空和此Activity有关的图片请求 Glide.with(fragment);// 同上 Glide.with(context.getApplicationContext());// 全局的Glide,和具体的生命周期无关。
动画
默认动画
//可以传入渐变事件 Glide.with(context).load(netUrl).crossFade(300).into(iv);
自定义动画
Glide.with(context).load(netUrl).animate(android.R.anim.slide_in_left).into(iv);
禁止动画
//don't Glide.with(context).load(netUrl).dontAnimate().into(iv);
transform ###
我们可以对加载过来的图片做转换,之后再设置给ImageView。我们以圆角头像举例,大家也可以自定义一些滤镜效果。
class CircleImageTransform extends BitmapTransformation{ public CircleImageTransform(Context context) { super(context); } @Override protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) { // pool.get() Bitmap bitmap = Bitmap.createBitmap(outWidth, outHeight, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); BitmapShader shader = new BitmapShader(toTransform, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); Matrix matrix=new Matrix(); float min=Math.min(outHeight*1.0f/toTransform.getHeight(),outWidth*1.0f/toTransform.getWidth()); matrix.setScale(min,min); shader.setLocalMatrix(matrix); Paint paint = new Paint(); paint.setAntiAlias(true); paint.setShader(shader); canvas.drawCircle(outWidth / 2, outHeight / 2, Math.min(outHeight / 2, outHeight / 2), paint); return bitmap; } @Override // 和缓存的key,有关. // 作为 缓存key的一部分,唯一 public String getId() { return getClass().getSimpleName(); } }
加载代码
Glide.with(this).load(netUrl).transform(new CircleImageTransform(this)).into(iv);
监听
RequestListener
Glide.with(this).load("").asBitmap().listener(new RequestListener<String, Bitmap>() { @Override public boolean onException(Exception e, String model, Target<Bitmap> target, boolean isFirstResource) { e.printStackTrace(); // 不要返回true,仅仅是打印错误日志 // 如果返回true。错误图片将不会显示 return false; } @Override public boolean onResourceReady(Bitmap resource, String model, Target<Bitmap> target, boolean isFromMemoryCache, boolean isFirstResource) { // 不要返回true // 否则正常图片无法显示 Log.e("tag",model); return false; } }).into(iv);