Glide作为谷歌的“亲儿子”,在项目使用的频率还是很高的,由于其功能强大,与picasso不相上下,各有优势,所以大家比较喜欢讨论其和picasso的优缺点。
网上也能找到很多Glide的使用说明,在这里就不做赘述了,直接上Demo的代码片段,后面再解释下Glide的自定义圆角和原型。
MainActivity的代码如下
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
public static final String RESOURCE = "android.resource://";
public static final String SLASH = "/";
private Context context;
private String path = "/androidesk/wallpapers/57484f7869401b103938f52a.jpg";
private int resId = R.mipmap.ic_launcher;
private String url_img = "http://images.cnitblog.com/blog/430074/201302/01220037-4e6a57c1199748fea9f8391e7e0548d7.jpg";
private String url_gif = "http://pic.uuhy.com/uploads/2011/02/11/005.gif";
ImageView iv;
private Button btn1, btn2, btn3, btn4, btn5, btn6;
private RequestManager glideRequest;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
initView();
}
private void initView() {
iv = (ImageView) findViewById(R.id.imageview_activity_main);
btn1 = (Button) findViewById(R.id.btn1);
btn2 = (Button) findViewById(R.id.btn2);
btn3 = (Button) findViewById(R.id.btn3);
btn4 = (Button) findViewById(R.id.btn4);
btn5 = (Button) findViewById(R.id.btn5);
btn6 = (Button) findViewById(R.id.btn6);
btn1.setOnClickListener(this);
btn2.setOnClickListener(this);
btn3.setOnClickListener(this);
btn4.setOnClickListener(this);
btn5.setOnClickListener(this);
btn6.setOnClickListener(this);
glideRequest = Glide.with(this);
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.btn1:
//加载资源中的图片
Glide.with(context).load(R.mipmap.ic_launcher).into(iv);
break;
case R.id.btn2:
//加载网络图片
// Glide.with(context).load(url_img).into(iv);
Glide.with(context).load(url_img).centerCrop().placeholder(R.mipmap.ic_launcher).error(R.mipmap.ic_launcher).priority(Priority.HIGH).crossFade().into(iv);
break;
case R.id.btn3:
//加载Gif图片
Glide.with(context).load(url_gif).placeholder(R.mipmap.ic_launcher).error(R.mipmap.ic_launcher).into(iv);
break;
case R.id.btn4:
//加载文件中的图片
File file = new File(Environment.getExternalStorageDirectory().getPath() + path);
Glide.with(context).load(file).into(iv);
//加载Uri中的图片
// Uri uri = Uri.parse(RESOURCE + getPackageName() + SLASH + resId);
// Glide.with(context).load(uri).into(iv);
break;
case R.id.btn5:
glideRequest.load(url_img).transform(new GlideCircleTransform(context)).into(iv);
break;
case R.id.btn6:
glideRequest.load(url_img).transform(new GlideRoundTransform(context)).into(iv);
// glideRequest.load("https://www.baidu.com/img/bdlogo.png").transform(new GlideRoundTransform(context, 10)).into(imageView);
break;
}
}
}
布局文件如下
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btn1"
android:text="加载本地图片"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btn2"
android:text="加载网络图片"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btn3"
android:text="加载网络gif"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btn4"
android:text="加载本地路径"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btn5"
android:text="加载自定义圆形图片"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btn6"
android:text="加载自定义圆角图片"/>
<ImageView
android:id="@+id/imageview_activity_main"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center_horizontal"/>
</LinearLayout>
自定义的圆形和圆角
/**
* Created by zhangshuyang01 on 2017/7/25 0025.
*/
public class GlideCircleTransform extends BitmapTransformation {
/**圆形图片*/
public GlideCircleTransform(Context context) {
super(context);
}
@Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
return circleCrop(pool, toTransform);
}
@Override
public String getId() {
return getClass().getName();
}
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;
// TODO this could be acquired from the pool too
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;
}
}
/**
* Created by zhangshuyang01 on 2017/7/25 0025.
*/
public class GlideRoundTransform extends BitmapTransformation {
/**
* 圆角图片
*/
private static float radius = 0f;
public GlideRoundTransform(Context context) {
this(context, 4);
}
public GlideRoundTransform(Context context, int dp) {
super(context);
this.radius = Resources.getSystem().getDisplayMetrics().density * dp;
}
@Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
return roundCrop(pool, toTransform);
}
@Override
public String getId() {
return getClass().getName() + Math.round(radius);
}
private static Bitmap roundCrop(BitmapPool pool, Bitmap source) {
if (source == null) return null;
Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
if (result == null) {
result = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(result);
Paint paint = new Paint();
paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
paint.setAntiAlias(true);
RectF rectF = new RectF(0f, 0f, source.getWidth(), source.getHeight());
canvas.drawRoundRect(rectF, radius, radius, paint);
return result;
}
}
清除缓存
/**
* 清除缓存
* @param context
*/
public
void
clearCache(
final
Context context ){
clearMemoryCache( context );
new
Thread(
new
Runnable() {
@Override
public
void
run() {
clearDiskCache( context );
}
}).start();
}
/**
* 清除内存缓存
* @param context
*/
public
void
clearMemoryCache( Context context ){
Glide.get( context ).clearMemory();
}
/**
* 清除磁盘缓存
* @param context
*/
public
void
clearDiskCache( Context context ){
Glide.get( context ).clearDiskCache();
}
transform(xxx)
接收的参数类型有两种,一种是
BitmapTransformation
,另一种是
Transformtion<GifBitmapWrapper>
,下面是它们的定义,在平时的使用过程中,如果我们的资源为静态图片,而不是
Gif
或者
Media
,那么通过继承
BitmapTransformation
来实现自己的变换就可以了。
BitmapTransformation
是实现了Transformation
的抽象类,它实现了transform(Resource<T> resource, int outWidth, int outHeight)
这个方法,并在里面调用了下面这个方法让子类去实现,也就是我们例子中实现的抽象方法,这主要是方便我们通过BitmapPool
对Bitmap
对象进行复用,同时使用者只用关心需要变换的Bitmap
,BitmapTransformation
会负责把它更新回原来的Resource
对象中。
protected abstract Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight);
对于这个方法的实现,有几个需要注意的点:
- 对于传入的
toTransform Bitmap
,不要去回收它或者把它放入到缓存池。如果实现者返回了一个不同的Bitmap
实例,Glide
会负责去回收或者复用toTransform
这个Bitmap
。 - 不要去回收作为这个方法返回值的
bitmap
。 - 如果在这个方法的执行过程中产生了临时的
Bitmap
实例,那么最好把它放入缓存池,或者回收它。
七、自定义 GlideModule
自定义 GlideModule 的好处:
1、可以全局的改变 glide 的加载策略
2、可以自定义磁盘缓存目录
3、可以设置图片加载的质量
7.1 首先定义一个类实现 GlideModule
1
2
3
4
5
6
7
8
9
10
11
12
|
public
class
SimpleGlideModule
implements
GlideModule {
@Override
public
void
applyOptions(Context context, GlideBuilder builder) {
}
@Override
public
void
registerComponents(Context context, Glide glide) {
}
}
|
可以看到重写了两个方法,applyOptions() , registerComponents() . 两个方法都没有返回值 。我们着重于第一个方法,重点研究 GlideBuilder 。
7.2 然后在 AndroidManifest.xml 去申明你写的 SimpleGlideModule
1
2
3
|
<meta-data
android:name=
"app.zuil.com.glidedemo.util.SimpleGlideModule"
android:value=
"GlideModule"
/>
|
name是:包名 + 类名
7.3 GlideBuilder
- .setMemoryCache(MemoryCache memoryCache)
- .setBitmapPool(BitmapPool bitmapPool)
- .setDiskCache(DiskCache.Factory diskCacheFactory)
- .setDiskCacheService(ExecutorService service)
- .setResizeService(ExecutorService service)
- .setDecodeFormat(DecodeFormat decodeFormat)
可以看到 setBitmapPool() 是设置bitmap池的 ; setDecodeFormat() 是设置解码方式的 ; setDiskCache() 是设置磁盘缓存的 ;
7.4 DecodeFormat
Android里有两个方法去解析图片:ARGB8888
和RGB565
。第一个为每个像素采用4 byte表示,后面一个则用2 byte表示。ARG8888
有更高的图片质量,并且能够存储一个alpha通道。Glide默认使用低质量的RGB565
。你可以通过使用Glide module方法改变解析格式。
最后一个完整的自定义glideModule
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
public
class
SimpleGlideModule
implements
GlideModule {
@Override
public
void
applyOptions(Context context, GlideBuilder builder) {
//定义缓存大小为100M
int
diskCacheSize =
100
*
1024
*
1024
;
//自定义缓存 路径 和 缓存大小
String diskCachePath = Environment.getExternalStorageDirectory().getAbsolutePath() +
"/glideCache"
;
//提高图片质量
builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
//自定义磁盘缓存:这种缓存只有自己的app才能访问到
// builder.setDiskCache( new InternalCacheDiskCacheFactory( context , diskCacheSize )) ;
// builder.setDiskCache( new InternalCacheDiskCacheFactory( context , diskCachePath , diskCacheSize )) ;
//自定义磁盘缓存:这种缓存存在SD卡上,所有的应用都可以访问到
builder.setDiskCache(
new
DiskLruCacheFactory( diskCachePath , diskCacheSize ));
}
@Override
public
void
registerComponents(Context context, Glide glide) {
}
}
|
demo可去github上获取。地址