到目前为止,网上有很多图片加载库,我就先来说说为什么选择Glide来学习。
Glide的特点
- 显示图片平缓流畅速度快
- 支持gif和webp格式图片
- 扩展性高可以转换各种图片效果
- 根据Activity/Fragment生命周期自动管理请求
- ...
其它图片加载库有的Glide都有,这里的特点是其它加载库没有的,还有很多特点这里就不一一列举,是不是觉得很心动,下面我们就来学习怎么使用Glide吧~
github地址:https://github.com/bumptech/glide
这里主要是介绍在Andrid Studio上使用
配置环境
在builde.gradle里面添加上
compile 'com.github.bumptech.glide:glide:3.7.0'
compile 'com.android.support:support-v4:19.1.0'
要说明的是glide是要依赖于support liberary v4
在AndroidManifest.xml添加所需权限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
基本使用
ImageView imageView = (ImageView)findViewById(R.id.my_image_view);
Glide.with(this).load("http://goo.gl/gEgYUd").into(imageView);
是不是特别简单一行代码就搞定
常用配置
- 设置图片格式
- 设置缓存目录(data或SD卡)
- 设置内存和硬盘缓存大小
创建MyGlideModule.java(名字可以随便取)实现GlideModule接口,实现里面两个方法
public class MyGlideModule implements GlideModule{
@Override
public void applyOptions(Context context, GlideBuilder builder) {
//设置格式
builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
//缓存到data目录下最大50M
//缓存目录为程序内部缓存目录/data/data/your_package_name/image_manager_disk_cache/(不能被其它应用访问)且缓存最大为250MB
builder.setDiskCache(new InternalCacheDiskCacheFactory(context,DiskCache.Factory.DEFAULT_DISK_CACHE_DIR,DiskCache.Factory.DEFAULT_DISK_CACHE_SIZE));
//缓存到外部磁盘SD卡上,字节
//builder.setDiskCache(new ExternalCacheDiskCacheFactory(context,DiskCache.Factory.DEFAULT_DISK_CACHE_DIR, DiskCache.Factory.DEFAULT_DISK_CACHE_SIZE));
//设置内存缓存大小
MemorySizeCalculator calculator = new MemorySizeCalculator(context);
int defaultMemoryCacheSize = calculator.getMemoryCacheSize();
int defaultBitmapPoolSize = calculator.getBitmapPoolSize();
int customMemoryCacheSize = (int) (1.2 * defaultMemoryCacheSize);
int customBitmapPoolSize = (int) (1.2 * defaultBitmapPoolSize);
builder.setMemoryCache(new LruResourceCache(customMemoryCacheSize));
builder.setBitmapPool(new LruBitmapPool(customBitmapPoolSize));
}
@Override
public void registerComponents(Context context, Glide glide) {
//glide.register(ImageFid.class,InputStream.class, new ImageFidLoader.Factory());
}
}
在AndroidManifest.xml配置,需要把包名更换成大家项目中MyGlideModule的包名
<application
...>
<meta-data
android:name="包名.MyGlideModule"
android:value="GlideModule" />
</application>
设置格式ARGB_8888
builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
设置缓存到data目录下
/data/data/your_package_name/image_manager_disk_cache/
DiskCache.Factory.DEFAULT_DISK_CACHE_DIR为默认缓存目录名image_manager_disk_cache,可以修改自己想要的名称
DiskCache.Factory.DEFAULT_DISK_CACHE_SIZE为默认缓存大小250M,参数单位是字节Byte,250M则是 250 ×1024×1024Byte
builder.setDiskCache(
new InternalCacheDiskCacheFactory(context,
DiskCache.Factory.DEFAULT_DISK_CACHE_DIR,
DiskCache.Factory.DEFAULT_DISK_CACHE_SIZE));
设置缓存到SD卡下
builder.setDiskCache(
new ExternalCacheDiskCacheFactory(context,
DiskCache.Factory.DEFAULT_DISK_CACHE_DIR,
DiskCache.Factory.DEFAULT_DISK_CACHE_SIZE));
设置内存缓存大小,这里设置的是默认大小的1.2倍,默认大小是多少还没有测试下,大家可以运行打印一下看看
MemorySizeCalculator calculator = new MemorySizeCalculator(context);
int defaultMemoryCacheSize = calculator.getMemoryCacheSize();
int defaultBitmapPoolSize = calculator.getBitmapPoolSize();
int customMemoryCacheSize = (int) (1.2 * defaultMemoryCacheSize);
int customBitmapPoolSize = (int) (1.2 * defaultBitmapPoolSize);
builder.setMemoryCache(new LruResourceCache(customMemoryCacheSize));
builder.setBitmapPool(new LruBitmapPool(customBitmapPoolSize));
获取缓存大小和清除缓存
- 清除内存缓存
public void clearMemory(Context context){
// 必须在UI线程中调用
Glide.get(context).clearMemory();
}
- 清除磁盘缓存
public void clearDiskCache(Context context){
// 必须在后台线程中调用,建议同时clearMemory()
Glide.get(context).clearDiskCache();
}
- 清除view缓存
public void clearViewCache(View view){
Glide.clear(view);
}
- 获取缓存大小
public void getDiskCacheSize(Context context,TextView textView){
//获取data下
new GetDiskCacheSizeTask(textView).execute(new File(context.getCacheDir(),DiskCache.Factory.DEFAULT_DISK_CACHE_DIR));
//获取sd卡下
//new GetDiskCacheSizeTask(textView).execute(new File(context.getExternalCacheDir(),DiskCache.Factory.DEFAULT_DISK_CACHE_DIR));
}
class GetDiskCacheSizeTask extends AsyncTask<File, Long, Long>{
private final TextView resultView;
public GetDiskCacheSizeTask(TextView resultView) {
this.resultView = resultView;
}
@Override
protected void onPreExecute() {
resultView.setText("Calculating...");
}
@Override
protected void onProgressUpdate(Long... values) { /* onPostExecute(values[values.length - 1]); */ }
@Override
protected Long doInBackground(File... dirs) {
try {
long totalSize = 0;
for (File dir : dirs) {
publishProgress(totalSize);
totalSize += calculateSize(dir);
}
return totalSize;
} catch (RuntimeException ex) {
final String message = String.format("Cannot get size of %s: %s", Arrays.toString(dirs), ex);
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
resultView.setText("error");
Toast.makeText(resultView.getContext(),message,Toast.LENGTH_LONG).show();
}
});
}
return 0L;
}
@Override
protected void onPostExecute(Long size) {
String sizeText = android.text.format.Formatter.formatFileSize(resultView.getContext(), size);
resultView.setText(sizeText);
}
private long calculateSize(File dir) {
if (dir == null) return 0;
if (!dir.isDirectory()) return dir.length();
long result = 0;
File[] children = dir.listFiles();
if (children != null)
for (File child : children)
result += calculateSize(child);
return result;
}
}
加载本地资源转换
//SD卡下图片
public String getSDSource(String fullPath){
return "file://"+ fullPath;
}
//ASSETS下图片
public String getAssetsSource(String fileName){
return "file:///android_asset/"+fileName;
}
//Raw下视频可以解析一张图片
public String getRawSource(Context context,int rawRid){
return "android.resource://"+context.getPackageName()+"/raw/"+rawRid;
}
//Drawable图片
public String getDrawableSource(Context context,int drawRid){
return "android.resource://"+context.getPackageName()+"/drawable/"+drawRid;
}
常用方法
Glide.with(context)
.load(url) //加载资源
.thumbnail(0.1f) //用原图的1/10作为缩略图,如果缩略图比全尺寸图先加载完,就显示缩略图,否则就不显示
//.thumbnail(getDrawableRequestBuilder(context,rid)) //本地资源作为缩略图
.centerCrop() //设置scaleType
.placeholder(null) //设置资源加载过程中的占位Drawable。
.crossFade() //设置加载渐变动画
.priority(Priority.NORMAL) //指定加载的优先级,优先级越高越优先加载,但不保证所有图片都按序加载。枚举Priority.IMMEDIATE,Priority.HIGH,Priority.NORMAL,Priority.LOW。默认为Priority.NORMAL。
.fallback(null) //设置model为空时要显示的Drawable。如果没设置fallback,model为空时将显示error的Drawable,如果error的Drawable也没设置,就显示placeholder的Drawable。
.error(null) //设置load失败时显示的Drawable。
.listener(listener) //请求监听
.skipMemoryCache(true) //设置跳过内存缓存,但不保证一定不被缓存(比如请求已经在加载资源且没设置跳过内存缓存,这个资源就会被缓存在内存中)。
.diskCacheStrategy(DiskCacheStrategy.RESULT) //缓存策略DiskCacheStrategy.SOURCE:缓存原始数据,DiskCacheStrategy.RESULT:缓存变换(如缩放、裁剪等)后的资源数据,DiskCacheStrategy.NONE:什么都不缓存,DiskCacheStrategy.ALL:缓存SOURC和RESULT。默认采用DiskCacheStrategy.RESULT策略,对于download only操作要使用DiskCacheStrategy.SOURCE。
.bitmapTransform(new CropCircleTransformation(context)) //圆角裁切
.into(imageView);
.thumbnail(0.1f)
用原图的1/10作为缩略图,如果缩略图比全尺寸图先加载完,就显示缩略图,否则就不显示
.thumbnail(getDrawableRequestBuilder(context,rid))
用本地资源作为缩略图
public DrawableRequestBuilder<Integer> getDrawableRequestBuilder(Context context,int drawRid){
return Glide
.with(context)
.load(drawRid);
}
.placeholder(Drawable)
设置资源加载过程中的占位Drawable
.fallback(Drawable)
设置为空显示的Drawable
.error(Drawable)
设置加载失败显示的Drawable
.crossFade()
设置加载渐变动画
.diskCacheStrategy(DiskCacheStrategy.RESULT)
设置缓存策略,DiskCacheStrategy.SOURCE:缓存原始数据,DiskCacheStrategy.RESULT:缓存变换(如缩放、裁剪等)后的资源数据,DiskCacheStrategy.NONE:什么都不缓存,DiskCacheStrategy.ALL:缓存SOURC和RESULT。默认采用DiskCacheStrategy.RESULT策略,对于download only操作要使用DiskCacheStrategy.SOURCE。
转换图片效果
在builde.gradle里面添加上
compile 'jp.wasabeef:glide-transformations:2.0.1'
github地址:https://github.com/wasabeef/glide-transformations
.bitmapTransform(new RoundedCornersTransformation(context,30,0, RoundedCornersTransformation.CornerType.ALL))
圆角处理
.bitmapTransform(new CropCircleTransformation(context))
圆形处理
..bitmapTransform(new GrayscaleTransformation(context))
灰度处理
...等等还有很多效果,感兴趣的可以上github上找找api尝试一些其它效果
如果想自定义图片效果也是可以滴
public class MyTransformation extends BitmapTransformation{
public MyTransformation(Context context) {
super(context);
}
@Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform,int outWidth, int outHeight) {
Bitmap result = pool.get(outWidth, outHeight, Bitmap.Config.ARGB_8888);
// 如果BitmapPool中找不到符合该条件的Bitmap,get()方法会返回null,就需要我们自己创建Bitmap了
if (result == null) {
// 如果想让Bitmap支持透明度,就需要使用ARGB_8888
result = Bitmap.createBitmap(outWidth, outHeight, Bitmap.Config.ARGB_8888);
}
//创建最终Bitmap的Canvas.
Canvas canvas = new Canvas(result);
Paint paint = new Paint();
paint.setAlpha(128);
// 将原始Bitmap处理后画到最终Bitmap中
canvas.drawBitmap(toTransform, 0, 0, paint);
// 由于我们的图片处理替换了原始Bitmap,就return我们新的Bitmap就行。
// Glide会自动帮我们回收原始Bitmap。
return result;
}
@Override
public String getId() {
// 返回代表该变换的唯一Id,会作为cache key的一部分。
// 注意:最好不要用getClass().getName(),因为容易受混淆影响。如果变换过程不影响缓存数据,可以返回空字符串。
return "com.example.myapp.MyTransformation";
}
}
Glide的学习也就到这里了,目前还没有在项目中用起来,大家用的过程中可能会碰到一些问题,欢迎给我评论留言,共同交流学习进步。
后面我也会陆续写一些其它库的学习文章,希望大家多多关注支持哈~
好记性不如烂笔头!