上面的这些Canvas方法固然已经很强大了,但是我们如果想要绘制一些不规则的图形怎么办,这时候就要用到强大的drawPath()方法了,通过对Path进行设置不同的坐标、添加不同图形,最后传入drawPath方法中可以绘制出复杂的且不规则的形状。以下是drawPath的方法及参数:
drawPath(Path path, Paint paint)
这里的关键参数就是Path,Path类的方法较多,大部分用法类似,这里挑几个说一下:
Path类
addArc(RectF oval, float startAngle, float sweepAngle) 往path里面添加一个圆弧
addCircle(float x, float y, float radius, Path.Direction dir) 添加一个圆形
addOval(RectF oval, Path.Direction dir) 添加一个椭圆
addRect(RectF rect, Path.Direction dir) 添加一个矩形
lineTo(float x, float y) 连线到坐标(x,y)
moveTo(float x, float y) 将path绘制点移动到坐标(x,y)
close() 用直线闭合图形,调用此方法后,path会将最后一处点与起始用直线连接起来,path起始点为moveTo()方法的坐标上,如果没有调用moveTo()起始点将默认为(0,0)坐标。
...
接下来使用drawPath绘制一个楼梯:
// 使用 Path 绘制一个楼梯 Path path = new Path(); path.lineTo(0, 1000); path.lineTo(100, 1000); path.lineTo(100, 1100); path.lineTo(200, 1100); path.lineTo(200, 1200); path.lineTo(300, 1200); path.lineTo(300, 1300); path.lineTo(400, 1300); path.lineTo(400, 1400); path.lineTo(0, 1400); path.lineTo(0, 1000); path.close(); canvas.drawPath(path, mPaint);效果如下图:
再用drawPath方法绘制一个Android小机器人:
/ 使用 Path 绘制一个Android机器人 // 绘制两个触角 path.reset(); path.moveTo(625, 1050); path.lineTo(650, 1120); path.moveTo(775, 1050); path.lineTo(750, 1120); path.addArc(new RectF(600, 1100, 800, 1300), 180, 180); // 绘制头部 path.addCircle(666.66f, 1150, 10, Path.Direction.CW); // 绘制眼睛,CW:顺时针绘制, CCW:逆时针绘制 path.addCircle(733.33f, 1150, 10, Path.Direction.CW); path.addRect(new RectF(600, 1200, 800, 1300), Path.Direction.CW); // 身体 canvas.drawPath(path, mPaint);效果图如下:
最后,上文中Canvas示例的全部代码如下:
public class StudyView extends View { private Paint mPaint; private Context mContext; public StudyView(Context context) { super(context); init(context); } public StudyView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(context); } private void init(Context context) { mContext = context; mPaint = new Paint(); mPaint.setAntiAlias(true); // 消除锯齿 mPaint.setStrokeWidth(5); // 设置笔尖宽度 mPaint.setStyle(Paint.Style.STROKE); // 不填充 } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); /** 1、drawArc */ // 绘制扇形 canvas.drawArc(0, 0, 200, 200, 0, 90, true, mPaint); RectF rectF = new RectF(0, 0, 200, 200); canvas.drawArc(rectF, 180, 90, true, mPaint); // 绘制圆弧 canvas.drawArc(300, 0, 500, 200, 0, 90, false, mPaint); RectF rectF1 = new RectF(300, 0, 500, 200); canvas.drawArc(rectF1, 180, 90, false, mPaint); /** 2、drawBitmap */ Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), android.R.mipmap.sym_def_app_icon); // 绘制图片 canvas.drawBitmap(bitmap, 0, 300, null); // 将图片拉伸平铺在RectF矩形内 canvas.drawBitmap(bitmap, null, new RectF(200, 300, 500, 500), null); // 截取图片的四分之一拉伸平铺在RectF矩形内 canvas.drawBitmap(bitmap, new Rect(0, 0, bitmap.getWidth()/2, bitmap.getHeight()/2), new RectF(500, 300, 800, 500), null); Matrix matrix = new Matrix(); matrix.postTranslate(800, 300); // 将bitmap平移到此位置 canvas.drawBitmap(bitmap, matrix, mPaint); // 为防止oom,及时回收bitmap bitmap.recycle(); /** 3、drawCircle */ canvas.drawCircle(100, 700, 100, mPaint); /** 4、绘制一个点 */ canvas.drawPoint(100, 700, mPaint); // 绘制一个点 float[] points = new float[] { 130, 700, 160, 700, 190, 700, 210, 700, 240, 700 }; canvas.drawPoints(points, 2, 4, mPaint); // 绘制一组点(代表跳过前两个值,处理4个值,也就是实际绘制2个点) RectF rectF2 = new RectF(300, 600, 700, 800); // 创建一个RectF /** 5、drawOval 绘制椭圆 */ canvas.drawOval(rectF2, mPaint); /** 6、drawRect 绘制矩形*/ canvas.drawRect(rectF2, mPaint); canvas.drawRoundRect(rectF2, 60, 30, mPaint); /** 7、drawLine */ canvas.drawLine(100, 820, 800, 820, mPaint); float[] lines = new float[]{ 100f, 850f, 800f, 850f, 100f, 900f, 800f, 900f, 100f, 950f, 800f, 950f }; canvas.drawLines(lines, mPaint); // 按floats数组中,四个数为1组,绘制多条线 /** 8、drawPath */ // 使用 Path 绘制一个楼梯 Path path = new Path(); path.moveTo(0, 1000); path.lineTo(100, 1000); path.lineTo(100, 1100); path.lineTo(200, 1100); path.lineTo(200, 1200); path.lineTo(300, 1200); path.lineTo(300, 1300); path.lineTo(400, 1300); path.lineTo(400, 1400); path.close(); canvas.drawPath(path, mPaint); // 使用 Path 绘制一个Android机器人 // 绘制两个触角 path.reset(); path.moveTo(625, 1050); path.lineTo(650, 1120); path.moveTo(775, 1050); path.lineTo(750, 1120); path.addArc(new RectF(600, 1100, 800, 1300), 180, 180); // 绘制头部 path.addCircle(666.66f, 1150, 10, Path.Direction.CW); // 绘制眼睛,CW:顺时针绘制, CCW:逆时针绘制 path.addCircle(733.33f, 1150, 10, Path.Direction.CW); path.addRect(new RectF(600, 1200, 800, 1300), Path.Direction.CW); // 身体 canvas.drawPath(path, mPaint); } }完整效果图如下: