Glide4.0 使用 +圆形图(Shader来实现)

有时候我们项目需要加载网络圆形图片 比如头像等,在这里我用的是Glide来加载圆形图的。

首先先把代码写下来:

RequestOptions optionsCircle = new RequestOptions();

DrawableTransitionOptions transitionOptions = new DrawableTransitionOptions();

Glide.with(mContext) .load(url) .apply(optionsCircle.transform(new GlideCircleTransform())).transition(transitionOptions.crossFade()) .into(imageView);

实现圆形图的是调用transform(new GlideCircleTransform()),GlideCircleTransform自定义继承BitmapTransformation实现的,代码如下:

public class GlideCircleTransform extends BitmapTransformation {

public GlideCircleTransform() { uper(); }

@Override

protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {

return circleCrop(pool, toTransform);

}

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;

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(newBitmapShader(squared,BitmapShader.TileMode.CLAMP,BitmapShader.TileMode.CLAMP));

paint.setAntiAlias(true);

float r = size / 2f;

canvas.drawCircle(r, r, r, paint);

return result; }

@Override

public void updateDiskCacheKey(MessageDigest messageDigest) { }

}

到此我们就实现了使用Glide加载圆形图了。查看代码发现核心方法是circleCrop(BitmapPool pool, Bitmap source)实现的。它是用canvas来画圆图的,

Paint paint = new Paint();

paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));

paint.setAntiAlias(true);

canvas.drawCircle(r, r, r, paint);

这是核心代码,发现是把bitmap赋值到paint来实现的,所以通过观察发现paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));这行代码我们用的很少,接下来就是重点介绍这行代码:

点进去查看源码发现,具体代码就不再这写了,可以自己查看。

setShader(Shader shader){

................

}

我们发现用到了一个类Shader,点进去看,发现对它的解释是这样的,

Shader is the based class for objects that return horizontal spans of colors during drawing. A subclass of Shader is installed in a Paint calling  paint.setShader(shader). After that any object (other than a bitmap) that is  drawn with that paint will get its color(s) from the shader. 

解释就是:Shader 是用于在绘图期间返回颜色水平范围的对象的基类。它的子类被安装在一个叫Paint . setshader (Shader)的中。之后,绘制的任何对象(除了位图之外)都将从Shader 中得到它的颜色。

因此我们就知道了,我们是如何使用canvas画出圆图得了。而且BitmapShader 就是shader的子类,BitmapShader 就是用来将图片来进行绘制的。

BitmapShader (Bitmap bitmap,Shader.TileMode tileX, Shader.TileMode tileY)

很多人对最后两个参数比较疑惑,点进去发现就是个枚举:

public enum TileMode {

/** * replicate the edge color if the shader draws outside of its original bounds */

CLAMP (0),

/** * repeat the shader's image horizontally and vertically */

REPEAT (1),

/** * repeat the shader's image horizontally and vertically, alternating  mirror images so that adjacent images always seam */ MIRROR (2);

TileMode(int nativeInt) { this.nativeInt = nativeInt; }

final int nativeInt; }

发现可以通过tiling mode来达到镜面和重复等效果。

那么为了更直观的观察他们的区别我们可以自定义一个view来查看他们的区别,我们只需实现以下就可以查看了:

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

int w = getWidth();

int h = getHeight();

Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.mipmap.dog);

 mShader =new BitmapShader(bmp, Shader.TileMode.REPEAT,Shader.TileMode.REPEAT);

mPaint.setShader(mShader);

canvas.drawRect(0,0,w,h,mPaint);

   }

然后我们在布局里:

    android:layout_width="match_parent"

    android:layout_height="400dp"/>

调用我们自定义的view即可 就可以了查看效果了。我们可以把Shader.TileMode.REPEAT,再替换成Shader.TileMode.MIRROR,Shader.TileMode.CLAMP来查看各自的效果,当然BitmapShader (Bitmap bitmap,Shader.TileMode tileX, Shader.TileMode tileY),最后两个参数是不需要保持一样,通过自己动手,可以很多好玩的东西。具体的可以自己试试,在这就不粘贴效果图了。通过学习Glide4.0 使用 +圆形图,我们发现了一个好玩的类Shader,我们可以用它实现很多东西,不仅仅局限于圆形图。等我们什么时候需要用到canvas时,我们就可以考虑是否可以用Shader来实现功能。

你可能感兴趣的:(Glide4.0 使用 +圆形图(Shader来实现))