图片加载之Glide
2016-04-25 07:39
246 查看
概述
作为Glide是谷歌推荐的图片加载库,Glide又着 支持video,Gif,SVG格式,同时有着很好的生命周期管理,支持Volley,OkHttp,更好的内存管理策略等优点。相关方法
with():指定了声明周期load():加载资源,String/Uri/File/Integer/URL/byte[]/T,或者 loadFromMediaStore(Uri uri)
placeholder(resourceId/drawable): 设置资源加载过程中的占位Drawable。
error():load失败时显示的Drawable。
crossFade()/crossFade(int duration):imageView改变时的动画,version 3.6.1后默认开启300毫秒
dontAnimate():移除所有的动画。
override() :调整图片大小
centerCrop():图片裁剪,ImageView 可能会完全填充,但图像可能不会完整显示。
fitCenter(): 图像裁剪,图像将会完全显示,但可能不会填满整个 ImageView。
animate(): 指定加载动画。
transform():图片转换。
bitmapTransform(): bitmap转换,不可以和(centerCrop() 或 fitCenter())共用。
priority(Priority priority):当前线程的优先级,Priority.IMMEDIATE,Priority.HIGH,Priority.NORMAL(default),Priority.LOW
thumbnail(): 缩略图.
listener():异常监听
preload(int width, int height): 预加载resource到缓存中(单位为pixel)
fallback(Drawable drawable):设置model为空时显示的Drawable。
using() :为单个的请求指定一个 model
asGif():Gif 检查,如果是图片且加了判断,则会显示error占位图,否则会显示图片
asBitmap():bitmap转化,如果是gif,则会显示第一帧
Glide 可以以load(File)的形式播放本地视频,但是如果需要播放网络视屏,则要用VideoView
缓存策略
一张图片变化很快,需要禁止内存缓存.skipMemoryCache(true)
即使关闭内存缓存,请求图片将会仍然被存储在设备的磁盘缓存中,如果一张图片变化很快,仍需要禁止磁盘缓存
.diskCacheStrategy(DiskCacheStrategy.NONE)
Glide 缓存了原始图像,全分辨率图像和另外小版本的图像,因此禁用磁盘缓存是用枚举来控制的
DiskCacheStrategy.NONE //什么都不缓存,就像刚讨论的那样 DiskCacheStrategy.SOURCE //仅仅只缓存原来的全分辨率的图像。在我们上面的例子中,将会只有一个 1000x1000 像素的图片 DiskCacheStrategy.RESULT //仅仅缓存最终的图像,即,降低分辨率后的(或者是转换后的) DiskCacheStrategy.ALL //缓存所有版本的图像(默认行为)
Glide使用InternalCacheDiskCacheFactory类建立磁盘缓存。目录在
/data/data/<package-name>/cache,其他应用程序无法访问。
自定义缓存策略:
磁盘缓存,用类DiskLruCacheWrapper来设置目录builder.setDiskCache(new DiskCache.Factory() { @Override public DiskCache build() { // 自己的缓存目录 File imgFile = new File(Environment.getExternalStorageDirectory()+"/Android/data/package-name"); return DiskLruCacheWrapper.get(imgFile,DiskCache.Factory.DEFAULT_DISK_CACHE_SIZE); } });
内存缓存,用类Memory Cache 来设置大小
MemorySizeCalculator calculator = new MemorySizeCalculator(context); builder.setMemoryCache(new LruResourceCache(calculator.getMemoryCacheSize()));
Bitmap Pool
重复使用及销毁策略。设置方法:GlideBuilder.setBitmapPool()默认采用的是LruBitmapPool,使用了LRU算法。
MemorySizeCalculator calculator = new MemorySizeCalculator(context); int defaultBitmapPoolSize = calculator.getBitmapPoolSize(); int customBitmapPoolSize = (int) (1.2 * defaultBitmapPoolSize); builder.setBitmapPool( new LruBitmapPool( customBitmapPoolSize );
Bitmap Format
Bitmap Format用于设置全局缺省首选Bitmap规格,设置方法:GlideBuilder.setDecodeFormat()默认采用RGB_565(比ARGB_8888节省一半的内存),但不支持透明度。
优先级
会发现优先级高的先 显示出来,即是图片比较大。//优先加载 Glide .with(context) .load(heroImageUrl) .priority(Priority.HIGH) .into(imageViewHero); //后加载 Glide .with(context) .load(itemImageUrl) .priority(Priority.LOW) .into(imageViewItem);
先显示缩略图,后显示原图
//用原图的1/10作为缩略图 Glide .with(this) .load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png") .thumbnail(0.1f) .into(iv_0); //用其它图片作为缩略图 DrawableRequestBuilder<Integer> thumbnailRequest = Glide .with(this) .load(R.drawable.news); Glide.with(this) .load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png") .thumbnail(thumbnailRequest) .into(iv_0);
图片处理
裁剪、模糊、滤镜等。可以s使用 wasabeef/glide-transformations ,实现Transformation 接口,或者使用抽象类BitmapTransformation,
通过transform()或bitmapTransform()来处理图片
//圆形裁剪 Glide.with(this) .load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png") .bitmapTransform(new CropCircleTransformation(this)) .into(iv_0); //圆角处理 Glide.with(this) .load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png") .bitmapTransform(new RoundedCornersTransformation(this,30,0, RoundedCornersTransformation.CornerType.ALL)) .into(iv_0); //灰度处理 Glide.with(this) .load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png") .bitmapTransform(new GrayscaleTransformation(this)) .into(iv_0); //模糊处理 Glide.with(this).load(R.drawable.demo) .bitmapTransform(new BlurTransformation(context)) .into((ImageView) findViewById(R.id.image)); //其它变换...
自定义转换
public class BlurTransformation extends BitmapTransformation { public BlurTransformation(Context context) { super( context ); } @Override protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) { return null; // todo } @Override public String getId() { return null; // todo } }
其中getId() :描述了这个转换的唯一标识符,将作为缓存系统的一部分
可以使用单种转换和多种转换,如多种转换:
Glide .with( context ) .load( eatFoodyImages[1] ) .transform( new GreyscaleTransformation( context ), new BlurTransformation( context ) ) .into( imageView2 );
回调 Target
SimpleTarget
target 泛型:Bitmap,GlideDrawable,GifDrawable其中使用字段声明target’而不是使用匿名内部类的形式,可以避免被垃圾回收机制回收,而回调为空的现象。
private SimpleTarget target = new SimpleTarget<Bitmap>() { @Override public void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) { // do something with the bitmap // for demonstration purposes, let's just set it to an ImageView imageView1.setImageBitmap( bitmap ); } }; private void loadImageSimpleTarget() { Glide .with( context ) // could be an issue! .load( eatFoodyImages[0] ) .asBitmap() .into( target ); }
Target生命周期
with( context ):关系到生命周期。如果请求需要在 activity 生命周期之外去做时,需要使用:private void loadImageSimpleTargetApplicationContext() { Glide .with( context.getApplicationContext() ) // safer! .load( eatFoodyImages[1] .asBitmap() .into( target2 ); }
Target 指定尺寸
使用ImageView 作为参数给 .into()的时候,Glide 会用 ImageView 的大小去限制图像的大小但是target并没有已知的大小,如果知道图片大小则应指出,减少内存消耗。
private SimpleTarget target2 = new SimpleTarget<Bitmap>( 250, 250 ) { @Override public void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) { imageView2.setImageBitmap( bitmap ); } }; private void loadImageSimpleTargetApplicationContext() { Glide .with( context.getApplicationContext() ) // safer! .load( eatFoodyImages[1] ) .asBitmap() .into( target2 ); }
ViewTarget
常用于自定以控件中,比如自定义控件中组合了ImageView控件,如下public class FutureStudioView extends FrameLayout { ImageView iv; TextView tv; public void initialize(Context context) { inflate( context, R.layout.custom_view_futurestudio, this ); iv = (ImageView) findViewById( R.id.custom_view_image ); tv = (TextView) findViewById( R.id.custom_view_text ); } public FutureStudioView(Context context, AttributeSet attrs) { super( context, attrs ); initialize( context ); } public FutureStudioView(Context context, AttributeSet attrs, int defStyleAttr) { super( context, attrs, defStyleAttr ); initialize( context ); } public void setImage(Drawable drawable) { iv = (ImageView) findViewById( R.id.custom_view_image ); iv.setImageDrawable( drawable ); } }
使用如下方法给自定义控件中的ImageView设置图片
private void loadImageViewTarget() { FutureStudioView customView = (FutureStudioView) findViewById( R.id.custom_view ); //传递了参数 customView viewTarget = new ViewTarget<FutureStudioView, GlideDrawable>( customView ) { @Override public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) { //调用了FutureStudioView的setImage方法 this.view.setImage( resource.getCurrent() ); } }; Glide .with( context.getApplicationContext() ) // safer! .load( eatFoodyImages[2] ) .into( viewTarget ); }
NotificationTarget
用于加载图片到通知栏和应用小部件中的,具体见 http://mrfu.me/动画
animate() :可以加载资源文件animate.xml文件或者 属性动画:
ViewPropertyAnimation
ViewAnimation
NoAnimation
DrawableCrossFadeViewAnimation
ViewPropertyAnimation.Animator animationObject = new ViewPropertyAnimation.Animator() { @Override public void animate(View view) { // if it's a custom view class, cast it here // then find subviews and do the animations // here, we just use the entire view for the fade animation view.setAlpha( 0f ); ObjectAnimator fadeAnim = ObjectAnimator.ofFloat( view, "alpha", 0f, 1f ); fadeAnim.setDuration( 2500 ); fadeAnim.start(); } }; Glide .with( context ) .load( eatFoodyImages[1] ) .animate( animationObject ) .into( imageView2 );
自定义Configuration
Glide module 是一个抽象方法,全局改变 Glide 行为的一个方式。前面单策略的定义中都用到了GlideBuilder类
如果你需要访问 GlideBuilder,你需要去实现一个 GlideModule 接口的公共类
public class FileGlideModule implements GlideModule{
@Override
public void applyOptions(final Context context, GlideBuilder builder) {
//builder 内的所有方法你都可以设置。
// builder.setDiskCache(new InternalCacheDiskCacheFactory(context));
builder.setDiskCache(new ExternalCacheDiskCacheFactory(context));
/* builder.setDiskCache(new DiskCache.Factory() {
@Override
public DiskCache build() {
File imgFile = new File(Environment.getExternalStorageDirectory()+"/Android/data/com.leying365");
return DiskLruCacheWrapper.get(imgFile,DiskCache.Factory.DEFAULT_DISK_CACHE_SIZE);
}
});*/
MemorySizeCalculator calculator = new MemorySizeCalculator(context); builder.setMemoryCache(new LruResourceCache(calculator.getMemoryCacheSize()));
builder.setBitmapPool(new LruBitmapPool(calculator.getBitmapPoolSize()));
builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
}
@Override
public void registerComponents(Context context, Glide glide) {
}
}
最终通过
<meta-data android:name=”com.mypackage.MyGlideModule” tools:node=”GlideModule” />来生效
常用方法:
setMemoryCache(MemoryCache memoryCache)
setBitmapPool(BitmapPool bitmapPool)
setDiskCache(DiskCache.Factory diskCacheFactory)
setDiskCacheService(ExecutorService service)
setResizeService(ExecutorService service)
setDecodeFormat(DecodeFormat decodeFormat)
网络库
Glide 使用ModeLoader 接口来 集成网络库,Glide提供了两种网络库 的实现,分别为OkHttp 和 Volley。在build.gradle中添加如下依赖,glide会默认使用OKhttp来做所有的网络连接
dependencies { // your other dependencies // ... // Glide compile 'com.github.bumptech.glide:glide:3.6.1' // Glide's OkHttp Integration compile 'com.github.bumptech.glide:okhttp-integration:1.3.1@aar' compile 'com.squareup.okhttp:okhttp:2.5.0' }
上面会将必要的GlideModule 到你的 Android.Manifest中。
使用demo:GlidePlayActivity.java
参考:http://mrfu.me/
相关文章推荐
- 个人工作总结07
- 第 2 章 基本格式
- 对输入法的评价
- 基于CefSharp构建基于Chromium的应用程序
- 【DDD/CQRS/微服务架构案例】在Ubuntu 14.04.4 LTS中运行WeText项目的服务端
- Gradle脚本的变量及其作用域
- Ubuntu 16.04 LTS安装好之后需要做的15件事
- [BZOJ1231][Usaco2008 Nov]mixup2 混乱的奶牛(状压dp)
- Ubuntu15.04 安装Geforce显卡驱动和CUDA
- SDUT 2164 Binomial Coeffcients 山东省第二届ACM大学生程序设计竞赛
- Spring AOP 实现机制
- SDUT 2163 Identifiers 山东省第二届ACM大学生程序设计竞赛
- 浅谈特定型人工智能设计
- OpenStack 通用设计思路 - 每天5分钟玩转 OpenStack(25)
- 如何选择 compileSdkVersion, minSdkVersion 和 targetSdkVersion
- 中国年薪 ¥30 万和美国年薪$ 10 万的生活水平异同 - 21世纪“中美国” - 知乎专栏
- OpenStack 通用设计思路 - 每天5分钟玩转 OpenStack(25)
- OpenStack 通用设计思路 - 每天5分钟玩转 OpenStack(25)
- 队项目个人工作总结(4月25日)
- ECMAScript运算符_一元运算符&位运算符&逻辑运算符&乘性运算符&加性运算符