Shader是一个很基础也很简单的功能,在自定义View中的使用频率很高。我们日常所见的各种圆角、圆形头像、多彩环形图都会出现他们的身影
基本概念
Shader类主要是渲染图像以及一些几何图形,目前有5个直接的子类
- BitmapShader : 主要用来渲染图像
- LinearGradient : 用来进行线性渲染
- RadialGradient : 用来进行环形渲染
- SweepGradient : 扫描渐变---围绕一个中心点扫描渐变就像电影里那种雷达扫描,用来梯度渲染。
- ComposeShader : 组合渲染,可以和其他几个子类组合起来使用。
TileMode类主要是在渲染器超出原始边界范围的时候,设置平铺的模式
- CLAMP:复制范围内边缘进行染色。
- REPEAT:横向和纵向的重复渲染器图片,平铺。
- MIRROR:横向和纵向的重复渲染器图片,这个和REPEAT重复方式不一样,他是以镜像方式平铺。
还有2个主要的方法
- boolean getLoaclMatrix(Matrix localM)
如果shader有一个非本地的矩阵将返回true。localM:如果不为null将被设置为shader的本地矩阵. - **void setLocalMatrix(Matrix localM); **
设置shader的本地矩阵,如果localM为空将重置shader的本地矩阵。
实战
接下来我们将通过学习,来了解如何通过Shader来实现这三个功能
- 圆角、圆形头像
@Overrideprotected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int width=getMeasuredWidth();
int height=getMeasuredHeight();
Matrix matrix=new Matrix();
Bitmap bmp=BitmapFactory.decodeResource(getResources(), R.mipmap.bg_banner);
int bmpWidth=bmp.getWidth();
int bmpHeight=bmp.getHeight();
float scale=(float) height/bmpHeight<(float) width/bmpWidth?(float) width/bmpWidth:(float) height/bmpHeight;
matrix.postScale(scale, scale);
matrix.postTranslate(-(bmpWidth*scale/2-getMeasuredWidth()/2), -(bmpHeight*scale/2-getMeasuredHeight()/2));
BitmapShader shader=new BitmapShader(bmp, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
shader.setLocalMatrix(matrix);
Paint paint=new Paint();
paint.setAntiAlias(true);
paint.setShader(shader);
if (width==height) {
canvas.drawCircle(getMeasuredWidth()/2, getMeasuredHeight()/2, getMeasuredWidth()
计算不同图片的宽高,然后缩放平移到中心点
- 多彩环形图
int width=getMeasuredWidth();
int height=getMeasuredHeight();
Paint paint=new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.LTGRAY);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(20);
canvas.drawCircle(width/2, height/2, width/2-20/2, paint);
int[] arcColors = new int[] {
0xFF09F68C,
0xFFB0F44B,
0xFFE8DD30,
0xFFF1CA2E,
0xFFFF902F,
0xFFFF6433,
0xFF09F68C};
SweepGradient sweepGradient=new SweepGradient(getMeasuredWidth()/2, getMeasuredHeight()/2, arcColors, null);
paint.setColor(Color.WHITE);
paint.setStrokeWidth(10);
PathEffect effects = new DashPathEffect(new float[] { 2, 4, 8, 16}, 20);
paint.setPathEffect(effects);
paint.setShader(sweepGradient);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
canvas.drawArc(new RectF(10, 10, width-10, height-10), -90, 270, false, paint);
使用SweepGradient可以直接画出圆弧,DashPathEffect可以画出虚线
OK,今天的东西就这么多,是不是很简单,以后在色彩上的需求,我们就可以轻松解决了