前言
Android 中的Canvas相当于是画布,通过画笔绘制几何图形,文本,路径和位图等;
常用Api分类:
- 绘制
- 变换
- 状态保存/恢复
简单看下第一种分类,不做重点介绍
绘制相关
void drawText(String text,int start, int end,Paint paint) //指定坐标 绘制文字
void drawPoint(float x, float y,Paint paint) //指定坐标 绘制点
void drawLine(float startX, float startY,float endX, float endY,Paint paint) //指定起始点,结束点 绘制连线
void drawPath(Path path,Paint paint) //指定path 绘制连线
void drawBitmap(Bitmap bitmap,float left,float top,Paint paint) //指定坐标,绘制位图
void drawCircle(float cx, float cy, float radius, Paint paint) //绘制圆形
void drawRect(RectF rect,Paint paint) //绘制矩形
等等等...
位置/形状 变换相关
void translate(float dx, float dy) //平移操作
void scale(float sx, float sy) //缩放操作
void rotate(float degrees) //旋转操作
void skew(float sx, float sy) //倾斜操作
void clipXxx(...) //切割操作,参数指定区域内可以正常(继续)绘制
void clipOutXxx(...) //反向切割操作,参数指定区域内不可以正常(继续)绘制
void setMatrix(Matrix matrix) :可通过matrix实现平移,缩放,旋转等操作
-
translate(float dx, float dy)
平移操作,操作画布平移,相当于绘制的参考点坐标平移,从坐标系的角度来说比较简单,直接看图:
translate(float dx, float dy) -
scale(float sx, float sy)
缩放操作,传入x,y方向的缩放比例,我们看下缩放前后对比(红色矩形为缩放前绘制,灰色矩形为缩放后绘制):
canvas.drawRect(200,200, 700,700, mPaint);
canvas.scale(0.5f, 0.5f);
mPaint.setColor(Color.GRAY);
canvas.drawRect(200,200, 700,700, mPaint);
scale(float sx, float sy)
scale(float sx, float sy)
操作对整个画布缩放操作,所以缩放后的绘制的矩形对比之前的,位置和大小都发生了变化,缩放操作还有个重载方法,需要四个参数void scale(float sx, float sy, float px, float py)
,我们看下前后对比
canvas.drawRect(200,200, 700,700, mPaint);
//先translate(px, py),再scale(sx, sy),再反向translate(px, py)
canvas.scale(0.5f, 0.5f,200,200);
mPaint.setColor(Color.GRAY);
canvas.drawRect(200,200, 700,700, mPaint);
void scale(float sx, float sy, float px, float py)
上述canvas.scale(0.5f, 0.5f,200,200)
操作相当于一下三行代码:
//先translate(px, py)
canvas.translate(200, 200);
//再scale(sx, sy)
canvas.scale(0.5f, 0.5f);
//再反向translate(px, py)
canvas.translate(-200, -200);
-
rotate(float degrees)
旋转操作
还有一个重载方法:
void rotate(float degrees, float px, float py)
//px, py表示旋转中心的坐标
默认顺时针旋转,直接看图:
canvas.drawRect(400, 400, 900, 900, mPaint);
canvas.rotate(45, 650, 650); //px, py表示旋转中心的坐标
mPaint.setColor(Color.GRAY);
canvas.drawRect(400, 400, 900, 900, mPaint);
rotate(float degrees, float px, float py)
-
void skew(float sx, float sy)
倾斜操作参数分别表示x,y方向倾斜的角度的tan值
canvas.drawRect(0,0, 400, 400, mPaint);
canvas.skew(1, 0); //在X方向倾斜45度,相当于Y轴逆时针旋转45
mPaint.setColor(Color.GRAY);
canvas.drawRect(0, 0, 400, 400, mPaint);
canvas.skew(1, 0)
如果在y方向倾斜45度的话
canvas.skew(0, 1); //在y方向倾斜45度, 相当于X轴顺时针旋转45
canvas.skew(0, 1)
-
void clipXxx(...)
//切割操作,参数指定区域内可以正常(继续)绘制,不在赘述 -
void clipOutXxx(...)
//反向切割操作,参数指定区域内不可以正常(继续)绘制,不在赘述 -
void setMatrix(Matrix matrix)
矩阵
Matrix
类里面封装了一系列的api,比如:
Matrix matrix = new Matrix();
matrix.setTranslate(50,50);//平移
matrix.setRotate(45);//旋转
matrix.setScale(0.5f, 0.5f);//酸防
canvas.setMatrix(matrix);
canvas.drawRect(0,0,700,700, mPaint);
状态保存和恢复
调用了translate,scale,rotate,skew,clipRect
等变换后,后续的操作都是基于
变换后的Canvas
,都会受到影响,对于后续的操作很不方便。Canvas提供 了save, saveLayer, saveLayerAlpha, restore,restore ToCount
来保存和恢复状态。
Canvas
的save()和restore()可以多次调用,Canvas内部维护了一个状态栈,每次save()
操作会将当前状态压栈,每次restore()
操作会将最上面的状态出栈,恢复到上次保存的状态
我们也可以调用canvas.getSaveCount()
获取当前保存的状态数,不进行任何的save()
操作,getSaveCount()
默认为1,调用canvas.getSaveCount()
恢复到指定状态,参数为save()
操作返回的int
值
int state = canvas.save(); //保存状态1
Log.e("TAG", "onDraw: " + canvas.getSaveCount());
canvas.translate(70, 50);
canvas.drawRect(0, 0, 400, 400, mPaint);
canvas.save(); //保存状态2
canvas.restore(); //返回最新状态(状态2)
Log.e("TAG", "onDraw: " + canvas.getSaveCount());
mPaint.setColor(Color.BLUE);
canvas.drawRect(0, 0, 400, 400, mPaint);
canvas.restoreToCount(state);//手动指定的返回到状态1
Canvas的总结就到这里,使用Canvas实现小案例见:
网友评论