前言
Canvas(画布)是用来画图形的,而Paint(画笔)则是用来指定画图形时用的颜色,宽度等样式信息
这里我们列举一些常用的API,方便新手快速上手
至于不常用的,和比较复杂的API,我们后面的课程用到时在详解
一来篇幅有限,复杂的难以讲清楚,二来也没必要将博客写成百科全书,比较偏的知识大家用到时百度即可
这篇博客建议大家快速扫一遍,有个印象后,直接看下篇教程
Paint常用API
//画笔API
Paint paint = new Paint();
paint.setAntiAlias(true); //抗锯齿,可以让图形边缘更平滑
paint.setColor(Colors.RED); //设置画笔颜色
paint.setStyle(Paint.Style.FILL); //填充
paint.setStyle(Paint.Style.STROKE); //描边
paint.setStyle(Paint.Style.FILL_AND_STROKE); //填充并描边
paint.setStrokeWidth(5); //画笔宽度
paint.setStrokeCap(Paint.Cap.ROUND); //线条端点形状
paint.setStrokeJoin(Paint.Join.ROUND); //线条连接处形状
paint.setPathEffect(new DashPathEffect(new float[]{20, 10, 50, 100}, 15)); //设置线条路径效果
paint.setTextSize(50); //设置文字大小
paint.setTextAlign(Paint.Align.LEFT); //设置文字对齐方式
paint.setTypeface(Typeface.DEFAULT); //设置字体
paint.setLetterSpacing(0.1F); //设置字符间距
paint.measureText("Hello"); //获取字符串宽度
paint.getTextBounds("Hello", 0, 5, new Rect()); //获取字符串位置区域
paint.setShader(new LinearGradient(0, 0, 0, 0, 0, 0, Shader.TileMode.MIRROR)); //设置渲染器,Shader决定了图形和特效如何组合成最终图像
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); //设置图形叠加模式,Xfermode决定了两个图形如何叠加
paint.setColorFilter(new LightingColorFilter(Colors.RED, 0)); //设置颜色过滤器,ColorFilter决定了图形和颜色如何叠加
paint.setMaskFilter(new BlurMaskFilter(10, BlurMaskFilter.Blur.NORMAL)); //设置滤镜效果
paint.setShadowLayer(5, 2, 2, Colors.RED); //设置阴影效果
paint.set(new Paint()); //将一个画笔的属性,拷贝到当前画笔
paint.reset(); //重置画笔所有设置
Canvas常用API
//画布API
Canvas canvas = null;
Paint paint = null;
Bitmap bitmap = null;
//给整个画布填充颜色
canvas.drawColor(Color.RED);
//以指定混合模式给整个画布填充颜色
canvas.drawColor(Color.RED, PorterDuff.Mode.ADD);
//通过Color清空画布
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
//通过Xfermode清空画布
paint.setColor(Color.TRANSPARENT);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawRect(new Rect(0, 0, 999, 999), paint);
//画点
canvas.drawPoint(100, 100, paint);
//画多条线,每2个float为一个点,每4个float为一条线
//4表示跳过前4个float,8表示连续画8个float,即画两条线
//数组、offset、count的值,都应当是4的整数倍
canvas.drawLines(new float[]{
100, 100, 300, 250,
0, 0, 400, 400,
200, 300, 500, 500,
100, 100, 300, 250
}, 4, 8, paint);
//画一条线,相当于canvas.drawLines(pointArray, 0, 4, paint)
canvas.drawLine(100, 100, 400, 400, paint);
//画两条线,相当于canvas.drawLines(pointArray, 0, 8, paint)
canvas.drawLines(new float[]{
100, 100, 300, 250,
0, 0, 400, 400
}, paint);
//画矩形
canvas.drawRect(100, 100, 600, 600, paint);
//画圆角矩形
canvas.drawRoundRect(100, 100, 600, 600, 20, 20, paint);
//画圆
canvas.drawCircle(350, 350, 250, paint);
//画椭圆
canvas.drawOval(100, 100, 600, 300, paint);
//画弧,false表示只画弧,true表示画包括半径在内的封闭扇形
canvas.drawArc(100, 100, 600, 600, 0, -90, false, paint);
//画任意几何路径
Path path = new Path();
path.addArc(100, 100, 500, 300, -180, 180); //在[100,100]-[500,300]的椭圆上,截取[-180°,0°]的弧
path.arcTo(600, 600, 1000, 800, -180, 180, true); //画一条新的弧,为true时是一条新的路径,为false时强制通过直线连接两条路径
path.lineTo(500, 1500); //画一条到指定位置的直线
canvas.drawPath(path, paint);
//画贝塞尔曲线
Path path2 = new Path();
path2.moveTo(300, 300); //移动画笔到[300,300]
path2.quadTo(500, 400, 700, 300); //以[300,300]为起点,[700,300]为终点,[500,400]为控制点,画二阶贝塞尔曲线
path2.moveTo(300, 300);
path2.rQuadTo(500, 400, 700, 300); //还是画二阶塞尔曲线,但这里的坐标,都是相对于[300,300]的相对位置
path2.moveTo(300, 300);
path2.cubicTo(500, 400, 600, 800, 700, 300); //画三阶贝塞尔曲线,比二阶多一个控制点
canvas.drawPath(path2, paint);
//画文字
canvas.drawText("Hello", 300, 300, paint);
//沿指定曲线路径画文字
Path path3 = new Path();
path3.moveTo(300, 300);
path3.quadTo(500, 400, 700, 300);
canvas.drawTextOnPath("Hello Hello Hello", path3, 0, 0, paint);
//画位图
canvas.drawBitmap(bitmap, 300, 300, paint);
//画位图的指定部分,到指定的Rect位置
canvas.drawBitmap(bitmap, new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()), new Rect(0, 0, 800, 400), paint);
//通过Picture绘制
//Picture对象不存储实际像素,只保存绘制过程
Picture picture = new Picture();
Canvas c = picture.beginRecording(400, 400);
c.drawLine(100, 100, 400, 400, paint);
picture.endRecording();
canvas.drawPicture(picture);
canvas.drawPicture(picture, new Rect(0, 0, 400, 400));
//通过PictureDrawable绘制
PictureDrawable pd = new PictureDrawable(picture);
pd.setBounds(new Rect(0, 0, 400, 400));
pd.draw(canvas);
//平移旋转画布
//本来在[0,0]处绘制的图形,将会被绘制到[100,100]处
//本来横向绘制的图形,将变为竖向
canvas.translate(100, 100);
canvas.rotate(90);
canvas.drawBitmap(bitmap, 0, 0, paint);
//通过矩阵画平移,缩放,旋转后的图像
Matrix matrix = new Matrix();
matrix.reset();
matrix.postTranslate(100, 200);
matrix.postScale(3, 3);
matrix.postRotate(20);
canvas.drawBitmap(bitmap, matrix, paint);
//裁剪绘制区域
//canvas默认的绘制区域是整个View范围
//当通过INTERSECT模式进行裁剪时,则只保留旧的区域与Rect相交的区域,作为新的绘制区域
//当通过DIFFERENCE模式进行裁剪时,则从旧的区域去除与Rect相交的区域,作为新的绘制区域
//clipRect可以调用多次,并且每次都是在上次结果之上,继续裁剪,范围只会越来越小,绝对不会变大
//想要回到最初的绘制区域,则需要通过save和restore来保存、还原画布状态
canvas.clipRect(new Rect(300, 300, 600, 600), Region.Op.INTERSECT);
canvas.clipRect(new Rect(300, 300, 600, 600), Region.Op.DIFFERENCE);
canvas.clipRect(new Rect(300, 300, 600, 600)); //相当于clipRect(Region.Op.INTERSECT)
canvas.clipOutRect(new Rect(300, 300, 600, 600)); //相当于clipRect(Region.Op.DIFFERENCE)
//通过Path裁剪绘制区域
//和clipRect功能一样,只是用Path区域代替Rect区域
Path path4 = new Path();
path4.moveTo(300, 300);
path4.lineTo(600, 300);
path4.lineTo(600, 600);
path4.lineTo(300, 600);
canvas.clipPath(path4);
//保存和还原画布状态
//saveLayer和save的功能一样,但saveLayer会同时生成一个新图层
//新操作将只会在这个图层图层上面操作,比如XferMode等操作,将不会影响到旧的图层
int saveCount = canvas.save(); //保存画布状态
saveCount = canvas.saveLayer(new RectF(0, 0, 1000, 1000), paint); //保存画布状态,同时生成一个新图层
canvas.restore(); //还原到最近一次保存的状态
canvas.restoreToCount(saveCount); //还原至指定的保存状态