void
drawBitmap
(Bitmap bitmap,float left,float top,Paint paint):在指定坐标绘制位图。
voiddrawLine
(float startX,float startY,float stopX,float stopY,Paint paint):根据给定的起始点和结束点之间绘制连线。
voiddrawPath
(Path path,Paint paint):根据给定的path,绘制连线。
voiddrawPoint
(float x,float y,Paint paint):根据给定的坐标,绘制点。
voiddrawText
(String text,int start,int end,Paint paint):根据给定的坐标,绘制文字。
…
void
translate
(float dx, float dy):平移操作void scale(float sx, float sy):缩放操作
voidrotate
(float degrees):旋转操作void skew(float sx, float sy):倾斜操作
voidclipXxx
(-…):切割操作,参数指定区域内可以继续绘制
voidclipOutXXX
(…):反向切割操作,参数指定区域内不可以绘制
voidsetMatrix
(Matrix matrix):可通过matrix实现平移,缩放,旋转等操作
//1、平移操作
canvas.drawRect(0, 0, 400, 400, mPaint);
canvas.translate(50,50);
mPaint.setColor(Color.BLUE);
canvas.drawRect(0, 0, 400, 400, mPaint);
canvas.drawLine(0,0,600,600,mPaint);
//2、缩放操作
canvas.drawRect(300, 300, 600, 600, mPaint);
canvas.scale(0.5f, 0.5f);
canvas.scale(0.5f, 0.5f, 300, 300);
// 先translate(px, py),再scale(sx, sy),再反向translate
canvas.translate(300, 300);
canvas.scale(0.5f, 0.5f);
canvas.translate(-300, -300);
mPaint.setColor(Color.BLUE);
canvas.drawRect(300, 300, 600, 600, mPaint);
canvas.drawLine(0,0,600,600,mPaint);
//3、旋转操作
canvas.drawRect(300, 300, 600, 600, mPaint);
// canvas.rotate(45);
canvas.rotate(30,450,450);//px,py表示旋转中心
mPaint.setColor(Color.BLUE);
canvas.drawRect(300, 300, 600, 600, mPaint);
理解:默认左上角为旋转中心。
// 4、倾斜操作
canvas.drawRect(0, 0, 300, 300, mPaint);
// canvas.skew(1,0);//在X方向倾斜45度,Y轴逆时针旋转45
canvas.skew(0, 1);//在Y方向倾斜45度,X轴顺时针旋转45
mPaint.setColor(Color.BLUE);
canvas.drawRect(0, 0, 300, 300, mPaint);
解释:skew中的两个参数非别为x,y方向上的tan值。如当sx为1时,表示x方向上对边比邻边为1,即向x正方向倾斜45度。另外,在手机上x,y的正方向分别为右,下。
//5、切割操作
canvas.drawRect(300, 300, 600, 600, mPaint);
canvas.clipRect(300, 300, 600, 600);//画布被裁剪
mPaint.setColor(Color.BLUE);
canvas.drawRect(350, 350, 650, 650, mPaint);//超出画布区域的无法绘制,画布内的可以正常绘制
canvas.drawRect(300, 300, 600, 600, mPaint);
canvas.clipOutRect(300, 300, 600, 600);//画布被裁剪
mPaint.setColor(Color.BLUE);
canvas.drawRect(350, 350, 650, 650, mPaint);//超出画布区域的无法绘制,画布内的可以正常绘制
解释:clipRect对应的是裁剪区域内可以绘制;clipOutRect对应的是裁剪区域外可以绘制。
显示效果
解释:红框为clipOutRect指定的区域,本例中在这个区域内绘制的圆无法显示。
//6、矩阵
canvas.drawRect(300, 300, 600, 600, mPaint);
Matrix matrix = new Matrix();
// matrix.setTranslate(50, 50);
// matrix.setRotate(45, 450, 450);
matrix.setScale(0.5f, 0.5f);
canvas.setMatrix(matrix);
mPaint.setColor(Color.BLUE);
canvas.drawRect(300, 300, 600, 600, mPaint);
解释:Matrix也有对应的平移,缩放,旋转等方法。
Canvas调用了translate,scale,rotate,skew,clipRect等变换后,后续的操作都是基于变换后的Canvas,都会受到影响,对于后续的操作很不方便。Canvas提供了save,saveLayer,saveLayerAlpha,restore,restoreToCount来保存和恢复状态。
解释:每restore一次,弹出一次,回到最近一次save时canvas的状态。也可以通过restoreToCount回到指定的save状态。
Log.e:默认为1;sava和restore数量必须一致,否则报错;打印结果:12321。
解释:先画红色大框,saveLayer相当于黄色框的范围。画布移动后,画了一个相当于蓝色范围的框,但是由于超出图层范围,显示不完全。restore之后画布回到屏幕左上角,画了一个小红框。
通过使用离屏缓冲,把要绘制的内容单独绘制在缓冲层,保证Xfermode的使用不会出现错误的结果。
使用离屏缓冲有两种方式:
Canvas.saveLayer()可以做短时的离屏缓冲。使用方法很简单,在绘制代码的前后各加一行代码,在绘制之前保存,绘制之后恢复:
int saveld = canvas.saveLayer(null, null, Canvas.ALL_SAVE_FLAG);Canvas.drawBitmap(rectBitmap, 0, o, paint);//画方
Paint.setXfermode(xfermode);//设置Xfermode
Canvas.drawBitmap(circleBitmap, o, 0, paint);//画圆Paint.setXfermode(null);//用完及时清除Xfermodecanvas.restoreToCount(saveld);
View.setLayerType()直接把整个View都绘制在离屏缓冲中。setLayerType(LAYER_TYPE_HARDWARE)使用GPU来缓冲,
setLayerType(LAYER_TYPE_SOFTWARE)使用一个Bitmap来缓冲。
一篇对Canvas有较为详细讲解的文章:讲解Canvas中的一些重要方法
扔物线(朱凯)视频教程:视频教程
自定义View系列文章:GcsSloop系列教程
本系列文章引导页点击这里
如果您有与本文相关的优质文章,欢迎在评论区推荐。