Glide简介:
Glide 是 Google 员工的开源项目, Google I/O 上被推荐使用,一个高效、开源、Android设备上的媒体管理框架,它遵循BSD、MIT以及Apache 2.0协议发布。Glide具有获取、解码和展示视频剧照、图片、动画等功能,它还有灵活的API,这些API使开发者能够将Glide应用在几乎任何网络协议栈里。创建Glide的主要目的有两个,一个是实现平滑的图片列表滚动效果,另一个是支持远程图片的获取、大小调整和展示。
Glide特点
依赖:compile 'jp.wasabeef:glide-transformations:3.0.1'
使用简单
可配置度高,自适应程度高
支持常见图片格式 Jpg png gif webp
支持多种数据源 网络、本地、资源、Assets 等
高效缓存策略 支持Memory和Disk图片缓存 默认Bitmap格式采用RGB_565内存使用至少减少一半
生命周期集成 根据Activity/Fragment生命周期自动管理请求
高效处理Bitmap 使用Bitmap Pool使Bitmap复用,主动调用recycle回收需要回收的Bitmap,减小系统回收压力
功能列表
0加载图片来自File
1加载图片来自资源id
2加载图片来自uri
3加载强制转化为gif
4加载原图的缩略图
5加载缩略图高级方式
6加载设置不缓存
7加载设置优先级
8加载回调后的图片
9加载回调后的图片设置尺寸
10加载图片圆角转换
11加载图片圆角转换2
0加载图片一般用法
1加载图片成功监听
2加载图片失败
3加载图片ID占位图
4加载图片Drawable占位图
5加载图片传入null
6加载图片后修改宽高
7加载图片后修改宽高等尺寸
8加载图片centerCrop
9加载图片fitCenter
10加载图片centerInside
11加载图片circleCrop
12加载动态图的第一帧
13加载动态图成功
14加载本地视频缩略图
代码实现:Activity
1 public class MainActivity extends AppCompatActivity implements View.OnClickListener { 2 3 protected ImageView iv; 4 protected Button btn; 5 protected String item; 6 private String STR_TAG = "--->***"; 7 private String TAG = this.getClass().getSimpleName(); 8 protected String result; 9 10 @Override 11 protected void onCreate(Bundle savedInstanceState) { 12 super.onCreate(savedInstanceState); 13 super.setContentView(R.layout.activity_main); 14 15 initView(); 16 } 17 18 private void initView() { 19 iv = (ImageView) findViewById(R.id.iv); 20 btn = (Button) findViewById(R.id.btn); 21 Button btn2 = (Button) findViewById(R.id.btn2); 22 btn.setOnClickListener(MainActivity.this); 23 btn2.setOnClickListener(MainActivity.this); 24 } 25 26 @Override 27 public void onClick(View view) { 28 if (view.getId() == R.id.btn) { 29 show(); 30 } else if (view.getId() == R.id.btn2) { 31 show0(); 32 } 33 } 34 35 private void show0() { 36 String[] items = { 37 "0加载图片来自File", 38 "1加载图片来自资源id", 39 "2加载图片来自uri", 40 "3加载强制转化为gif", 41 "4加载原图的缩略图", 42 "5加载缩略图高级方式", 43 "6加载设置不缓存", 44 "7加载设置优先级", 45 "8加载回调后的图片", 46 "9加载回调后的图片设置尺寸", 47 "10加载图片圆角转换", 48 "11加载图片圆角转换2", 49 }; 50 new AlertDialog.Builder(this) 51 .setTitle("glide操作2") 52 .setItems(items, new DialogInterface.OnClickListener() { 53 @Override 54 public void onClick(DialogInterface dialog, int which) { 55 switch (which) { 56 case 0: 57 selectedA0(); 58 break; 59 case 1: 60 selectedA1(); 61 break; 62 case 2: 63 selectedA2(); 64 break; 65 case 3: 66 selectedA3(); 67 break; 68 case 4: 69 selectedA4(); 70 break; 71 case 5: 72 selectedA5(); 73 break; 74 case 6: 75 selectedA6(); 76 break; 77 case 7: 78 selectedA7(); 79 break; 80 case 8: 81 selectedA8(); 82 break; 83 case 9: 84 selectedA9(); 85 break; 86 case 10: 87 selectedA10(); 88 break; 89 case 11: 90 selectedA11(); 91 break; 92 case 12: 93 break; 94 } 95 } 96 }).create() 97 .show(); 98 } 99 100 private void selectedA11() { 101 //RoundedCorners, 102 //CenterInside 103 Glide.with(this) 104 .load(UC.IMAGE_URL_A11) 105 .apply( 106 new RequestOptions() 107 .override(300) 108 .transform(new RoundedCorners(20)) 109 ) 110 .into(iv); 111 } 112 113 private void selectedA10() { 114 Glide.with(this) 115 .load(UC.IMAGE_URL_A10) 116 .apply(new RequestOptions().transform(new GlideRoundTransform(this))) 117 .into(iv); 118 } 119 120 private void selectedA9() { 121 //强制Glide返回一个Bitmap 122 SimpleTarget<Bitmap> target = new SimpleTarget<Bitmap>(300, 300) { 123 @Override 124 public void onResourceReady(Bitmap resource, Transition<? super Bitmap> transition) { 125 iv.setImageBitmap(resource); 126 } 127 }; 128 Glide.with(this).asBitmap() 129 .load(UC.IMAGE_URL_A9) 130 .into(target 131 ); 132 } 133 134 135 private void selectedA8() { 136 //上面这段代码不要写成匿名内部类的机制,原因就是java的自动垃圾回收机制可能在图片还没有加载好的时候就已经把你的Target回收了 137 //注意.with()里面的参数,Glide的请求是和传进去的Context共存亡的,如果传一个Activity进去,当Activity GG过后,你的请求也就GG了,但是如果这样传:.with(context.getApplicationContext() ).当你的Activity GG过后,请求还是会继续,回调还是会继续。 138 139 140 //强制Glide返回一个Bitmap 141 SimpleTarget<Bitmap> target = new SimpleTarget<Bitmap>() { 142 @Override 143 public void onResourceReady(Bitmap resource, Transition<? super Bitmap> transition) { 144 iv.setImageBitmap(resource); 145 } 146 }; 147 Glide.with(this).asBitmap() 148 .load(UC.IMAGE_URL_A8) 149 .into(target 150 ); 151 } 152 153 private void selectedA7() { 154 Glide.with(this) 155 .load(UC.IMAGE_URL_A7) 156 .apply(new RequestOptions().priority(Priority.LOW)) 157 .into(iv); 158 } 159 160 private void selectedA6() { 161 Glide.with(this) 162 .load(UC.IMAGE_URL_A6) 163 .apply(new RequestOptions().skipMemoryCache(true).diskCacheStrategy(DiskCacheStrategy.NONE)) 164 .into(iv); 165 } 166 167 private void selectedA5() { 168 //先加载第一张图片作为缩略图,在加载最终要显示的图片 169 //thumbnail中加载的是缩略图 170 Glide.with(this).load(UC.IMAGE_URL_9) 171 .thumbnail(Glide.with(this).load(UC.IMAGE_URL_A5)).into(iv); 172 } 173 174 private void selectedA4() { 175 //先加载为原图的十分之一,后再加载原图. 176 Glide.with(this) 177 .load(UC.IMAGE_URL_A4) 178 .thumbnail(0.1f) 179 .into(iv); 180 } 181 182 private void selectedA3() { 183 Glide.with(this).asGif().load(UC.GIF_URL_0).into(iv); 184 } 185 186 private void selectedA2() { 187 Glide.with(this) 188 .load(Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "d.jpg"))) 189 .into(iv); 190 } 191 192 private void selectedA1() { 193 Glide.with(this) 194 .load(R.mipmap.ic_launcher_round) 195 .into(iv); 196 } 197 198 private void selectedA0() { 199 File file = new File(Environment.getExternalStorageDirectory(), "3.jpg"); 200 Glide.with(this).load(file).into(iv); 201 } 202 203 private void show() { 204 final String[] items = { 205 "0加载图片一般用法", 206 "1加载图片成功监听", 207 "2加载图片失败", 208 "3加载图片ID占位图", 209 "4加载图片Drawable占位图", 210 "5加载图片传入null", 211 "6加载图片后修改宽高", 212 "7加载图片后修改宽高等尺寸", 213 "8加载图片centerCrop", 214 "9加载图片fitCenter", 215 "10加载图片centerInside", 216 "11加载图片circleCrop", 217 "12加载动态图的第一帧", 218 "13加载动态图成功", 219 "14加载本地视频缩略图", 220 221 }; 222 new AlertDialog.Builder(this) 223 .setTitle("glide操作选项") 224 .setItems(items, new DialogInterface.OnClickListener() { 225 @Override 226 public void onClick(DialogInterface dialog, int which) { 227 item = items[which] + STR_TAG; 228 switch (which) { 229 case 0: 230 selected0(); 231 break; 232 case 1: 233 selected1(); 234 break; 235 case 2: 236 selected2(); 237 break; 238 case 3: 239 selected3(); 240 break; 241 case 4: 242 selected4(); 243 break; 244 case 5: 245 selected5(); 246 break; 247 case 6: 248 selected6(); 249 break; 250 case 7: 251 selected7(); 252 break; 253 case 8: 254 selected8(); 255 break; 256 case 9: 257 selected9(); 258 break; 259 case 10: 260 selected10(); 261 break; 262 case 11: 263 selected11(); 264 break; 265 case 12: 266 selected12(); 267 break; 268 case 13: 269 selected13(); 270 break; 271 case 14: 272 selected14(); 273 break; 274 } 275 } 276 }).create() 277 .show(); 278 } 279 280 private void selected14() { 281 //缩略图的加载 282 String name = "v.f40.mp4"; 283 Glide.with(this).load(Uri.fromFile(new File(Environment.getExternalStorageDirectory(), name))) 284 .into(iv); 285 } 286 287 private void selected13() { 288 //GIF加载,URL指向的资源必须是gif,如果是普通图片则不显示。 289 //相反,如果指向正确但没有执行asGif方法,则只是作为普通图片展示 290 Glide.with(this).asGif().load(UC.GIF_URL_0).into(iv); 291 } 292 293 private void selected12() { 294 //可理解为加载动态图的第一帧的Bitmap,比如Gif 295 Glide.with(this).asBitmap(). 296 load(UC.GIF_URL_0).into(iv); 297 } 298 299 private void selected11() { 300 Glide.with(this) 301 .load(UC.IMAGE_URL_11) 302 .apply(new RequestOptions().circleCrop()) 303 .into(iv); 304 } 305 306 private void selected10() { 307 Glide.with(this) 308 .load(UC.IMAGE_URL_10) 309 .apply(new RequestOptions().centerInside()) 310 .into(iv); 311 } 312 313 private void selected9() { 314 Glide.with(this) 315 .load(UC.IMAGE_URL_8) 316 .apply(new RequestOptions().fitCenter()) 317 .into(iv); 318 } 319 320 private void selected8() { 321 RequestOptions options = new RequestOptions() 322 .centerCrop(); 323 Glide.with(this) 324 .load(UC.IMAGE_URL_9) 325 .apply(options) 326 .into(iv); 327 } 328 329 private void selected7() { 330 RequestOptions options = new RequestOptions().override(300).fitCenter(); 331 Glide.with(this) 332 .load(UC.IMAGE_URL_1) 333 .apply(options) 334 .into(iv); 335 } 336 337 private void selected6() { 338 RequestOptions options = new RequestOptions().override(400, 400).fitCenter(); 339 Glide.with(this).load(UC.IMAGE_URL_1) 340 .apply(options) 341 .into(iv); 342 } 343 344 private void selected5() { 345 RequestOptions options = new RequestOptions() 346 .fallback(R.mipmap.ic_launcher) 347 .diskCacheStrategy(DiskCacheStrategy.NONE); 348 Glide.with(this) 349 .load(null) 350 .apply(options) 351 .into(iv); 352 } 353 354 private void selected4() { 355 Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.load); 356 Drawable drawable = new BitmapDrawable(getResources(), bitmap); 357 RequestOptions options = new RequestOptions().placeholder(drawable); 358 Glide.with(this) 359 .load(UC.IMAGE_URL_ERROR) 360 .apply(options) 361 .into(iv); 362 } 363 364 private void selected3() { 365 RequestOptions options = new RequestOptions() 366 .placeholder(R.mipmap.load) 367 .error(R.mipmap.fail) 368 .fallback(R.mipmap.ic_launcher) 369 .diskCacheStrategy(DiskCacheStrategy.NONE); 370 Glide.with(this) 371 .load(UC.IMAGE_URL_ERROR) 372 .apply(options) 373 .into(iv); 374 } 375 376 private void selected2() { 377 Glide.with(this) 378 .load(UC.IMAGE_URL_ERROR) 379 .listener(new RequestListener<Drawable>() { 380 @Override 381 public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) { 382 DemonstrateUtil.showToastResult(MainActivity.this, "onLoadFailed失败"); 383 return false; 384 } 385 386 @Override 387 public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) { 388 DemonstrateUtil.showToastResult(MainActivity.this, "onResourceReady成功"); 389 return false; 390 } 391 }).into(iv); 392 } 393 394 private void selected1() { 395 396 Glide.with(this) 397 .load(UC.IMAGE_URL_1) 398 .listener(new RequestListener<Drawable>() { 399 @Override 400 public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) { 401 DemonstrateUtil.showToastResult(MainActivity.this, "onLoadFailed加载失败!"); 402 return false; 403 } 404 405 @Override 406 public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) { 407 DemonstrateUtil.showToastResult(MainActivity.this, "onResourceReady加载成功!"); 408 return false; 409 } 410 }) 411 .into(iv); 412 } 413 414 private void selected0() { 415 //默认使用原图加载,内存缓存,磁盘缓存, 416 Glide.with(this).load(UC.IMAGE_URL_0).into(iv); 417 } 418 419 420 }
图片地址:
1 public interface UC { 2 String IMAGE_URL_0 = "http://p0.so.qhmsg.com/t010b9ba7c1e568dd3f.jpg"; 3 String IMAGE_URL_1 = "http://img3.a0bi.com/upload/ttq/20160621/1466508726953.jpg"; 4 String IMAGE_URL_8= "http://www.285868.com/uploadfile/2016/1027/20161027102235543.jpg"; 5 String IMAGE_URL_ERROR = "http://p0.so.qhmsg.com/t010b9ba7c1e568dd3f66.jpg"; 6 String IMAGE_URL_9 = "http://img2.3lian.com/2014/f3/51/d/2.jpg"; 7 String IMAGE_URL_10 = "http://www.5djiaren.com/uploads/2015-10/24-175904_894.jpg"; 8 String IMAGE_URL_11 = "http://tupian.enterdesk.com/2013/mxy/0810/1/4.jpg"; 9 String IMAGE_URL_12 = "http://thumb.takefoto.cn/wp-content/uploads/2016/03/201603211236327864.jpg"; 10 11 String GIF_URL_0 = "http://uploads.rayli.com.cn/2016/0823/1471943453795.gif"; 12 String VIDEO_RUL_0 = "http://1251603248.vod2.myqcloud.com/4c9adaa7vodtransgzp1251603248/30e0819d9031868223192061218/v.f40.mp4"; 13 String IMAGE_URL_A4 = "http://www.hinews.cn/pic/0/10/24/62/10246261_856361.jpg"; 14 String IMAGE_URL_A5 = "http://img1.gtimg.com/0/1/168/16805_1200x1000_0.jpg"; 15 String IMAGE_URL_A6 = "http://img.mp.itc.cn/upload/20161104/d5737b849b6442ea9f594ddc3cbbc23a_th.jpeg"; 16 String IMAGE_URL_A7 = "http://5.26923.com/download/pic/000/330/4a9bfbb14275471e5ec956ad416b6194.jpg"; 17 String IMAGE_URL_A8 = "http://pic1.win4000.com/wallpaper/8/55f91ad3a23ea.jpg"; 18 String IMAGE_URL_A9 = "http://www.hinews.cn/pic/0/14/00/69/14006911_715505.jpg"; 19 String IMAGE_URL_A10 = "http://p4.so.qhmsg.com/t0199c5431414d2ea29.jpg"; 20 String IMAGE_URL_A11 = "http://p2.cri.cn/M00/1C/C0/CqgNOlm4oreAHkbcAAAAAAAAAAA69.3200x2000.jpeg"; 21 String IMAGE_URL_A12 = "http://img1.qq.com/ent/pics/10742/10742073.jpg"; 22 }
Transformation:
1 public class MyTransformation implements Transformation<Bitmap> { 2 3 private BitmapPool mBitmapPool; 4 private int mWidth; 5 private int mHeight; 6 7 public MyTransformation(Context context) { 8 this(Glide.get(context).getBitmapPool()); 9 } 10 11 public MyTransformation(BitmapPool pool) { 12 this.mBitmapPool = pool; 13 } 14 15 @Override 16 public Resource<Bitmap> transform(Context context, Resource<Bitmap> resource, int outWidth, int outHeight) { 17 Bitmap source = resource.get(); 18 int size = Math.min(source.getWidth(), source.getHeight()); 19 20 mWidth = (source.getWidth() - size) / 2; 21 mHeight = (source.getHeight() - size) / 2; 22 23 Bitmap.Config config = 24 source.getConfig() != null ? source.getConfig() : Bitmap.Config.ARGB_8888; 25 Bitmap bitmap = mBitmapPool.get(mWidth, mHeight, config); 26 if (bitmap == null) { 27 bitmap = Bitmap.createBitmap(source, mWidth, mHeight, size, size); 28 } 29 30 return BitmapResource.obtain(bitmap, mBitmapPool); 31 } 32 33 @Override 34 public void updateDiskCacheKey(MessageDigest messageDigest) { 35 36 } 37 }
实现圆角效果:
1 public class GlideRoundTransform extends BitmapTransformation { 2 private float radius = 0f; 3 4 public GlideRoundTransform(Context context) { 5 this(context, 20); 6 } 7 8 public GlideRoundTransform(Context context, int dp) { 9 super(context); 10 //density,屏幕密度.1.5,1,0.75 11 this.radius = Resources.getSystem().getDisplayMetrics().density * dp; 12 } 13 14 @Override 15 protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) { 16 return roundCrop(pool, toTransform); 17 } 18 19 private Bitmap roundCrop(BitmapPool pool, Bitmap source) { 20 if (source == null) return null; 21 //Bitmap.Config.ARGB_8888,图片质量. 22 Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888); 23 24 if (result == null) { 25 result = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888); 26 } 27 Canvas canvas = new Canvas(result); 28 Paint paint = new Paint(); 29 //REPEAT,MIRROR,CLAMP{重复,镜像,拉伸} 30 //设置着色器 31 paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP)); 32 //设置抗锯齿. 33 paint.setAntiAlias(true); 34 //矩阵,(float left, float top, float right, float bottom) 35 //矩形的左边的x坐标,矩形的顶部的Y坐标,对右侧的矩形的x坐标,矩形的底部的Y坐标 36 RectF rectF = new RectF(0f, 0f, source.getWidth(), source.getHeight()); 37 //画指定的圆矩形。 38 //drawRoundRect(RectF rect, float rx, float ry, @NonNull Paint paint) 39 //矩阵,圆角,椭圆的x半径,y半径.画笔, 40 canvas.drawRoundRect(rectF, radius, radius, paint); 41 return result; 42 43 } 44 45 @Override 46 public void updateDiskCacheKey(MessageDigest messageDigest) { 47 48 } 49 }
还有网络权限