本文共 7157 字,大约阅读时间需要 23 分钟。
上文中我们简单实现了使用自定义View
绘制一个边长100的正方形这个需求,不知道同学们掌握的怎么样了?接下来我们看下自定义View
中其他图形的绘制方式。
下表中罗列了Canvas
中绘图方法及说明(由于大多数方法都有多个重载实现,我们表中只列出比较常用的):
方法名 | 方法说明 | 备注 |
---|---|---|
drawPoint(float x, float y, @NonNull Paint paint) | 绘制点 | Paint #setStrokeWidth(float width) 设置点的大小 |
drawPoints(@Size(multiple = 2) @NonNull float[] pts, @NonNull Paint paint) | 绘制一组点 | Paint #setStrokeWidth(float width) 设置点的大小 |
drawLine(float startX, float startY, float stopX, float stopY, @NonNull Paint paint) | 绘制一条直线,起于(startX ,startY ),止于(stopX ,stopY ) | Paint #setStrokeWidth(float width) 设置线宽 |
drawLines(@Size(multiple = 4) @NonNull float[] pts, @NonNull Paint paint) | 绘制一组直线,pts 中四个值为一条直线的起终点 | Paint #setStrokeWidth(float width) 设置线宽 |
drawRect(float left, float top, float right, float bottom, @NonNull Paint paint) | 绘制一个以(left ,top )为左上角,(right ,bottom )为右下角大小的矩形 | Paint #setStyle(Style style) 设置是否是实心矩形,Paint #setStrokeWidth(float width) 设置线宽 |
drawRect(@NonNull Rect r, @NonNull Paint paint) | 以r 所描述的区域绘制矩形 | 同上 |
drawRect(@NonNull RectF rect, @NonNull Paint paint) | 以rect 所描述的区域绘制矩形 | 同上 |
drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, @NonNull Paint paint) | 绘制圆角矩形,前四个值说明同drawRect ,rx ,ry 用于指定圆角弧度 | 同上 |
drawCircle(float cx, float cy, float radius, @NonNull Paint paint) | 以(cx ,cy )为圆心,radius 为半径绘制圆 | Paint #setStyle(Style style) 设置是否是实心圆还是圆环,Paint #setStrokeWidth(float width) 设置圆环宽度 |
drawOval(float left, float top, float right, float bottom, @NonNull Paint paint) | 绘制以(left ,top )为左上角,(right ,bottom )为右下角矩形的内切椭圆 | Paint #setStyle(Style style) 设置是否是实心椭圆还是空心,Paint #setStrokeWidth(float width) 设置椭圆环宽度 |
drawBitmap(@NonNull Bitmap bitmap, float left, float top, @Nullable Paint paint) | 以(left ,top )为左上角绘制bitmap | |
drawBitmap(@NonNull Bitmap bitmap, @NonNull Matrix matrix, @Nullable Paint paint) | 绘制经matrix 矩形变换的bitmap | |
drawArc(@NonNull RectF oval, float startAngle, float sweepAngle, boolean useCenter, @NonNull Paint paint) | 绘制oval 所在矩形的内切椭圆上以startAngle 为起始角度,旋转sweepAngle 角度得到的弧或扇形 | 绘制是弧还是扇形取决于userCenter 及Paint #setStyle(Style style) |
drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean useCenter, @NonNull Paint paint) | 绘制以(left ,top )为左上角,(right ,bottom )为右下角矩形的内切椭圆上以startAngle 为起始角度,旋转`sweepAngle角度得到的弧或扇形 | 同上 |
drawText(@NonNull String text, float x, float y, @NonNull Paint paint) | 以(x ,y )起点基线绘制字符串 | |
下面我们一起来看下这些方法的基础使用及运行效果
//使用30线宽在(20,20)的位置绘制一个点//新建画笔Paint pointPaint = new Paint();//设置画笔颜色pointPaint.setColor(Color.BLUE);//设置画笔粗细pointPaint.setStrokeWidth(30);//调用canvas对象drawPoint函数绘制canvas.drawPoint(20,20,pointPaint);
//使用线宽10,在(20,60),(40,60)及(60,60)这三个位置各绘制一个点Paint pointsPaint = new Paint(Paint.ANTI_ALIAS_FLAG);//设置画笔颜色pointsPaint.setColor(Color.BLUE);//设置画笔粗细pointsPaint.setStrokeWidth(10);//设置点坐标,两两组成一个点坐标float[] pts = {20,60,40,60,60,60};调用canvas对象的drawPoints方法进行绘制canvas.drawPoints(pts,pointsPaint);
//以(20,1620)为基点绘制字符串Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);//设置字体画笔颜色textPaint.setColor(Color.BLUE);//设置字体大小textPaint.setTextSize(30);//设置字体样式textPaint.setTypeface(Typeface.DEFAULT_BOLD);canvas.drawText("Hello MyCustomView",20,1620,textPaint);
//绘制左上顶点为(20,620),右下顶点为(200,820)的矩形内切椭圆从0度到90所围成的封闭区域Paint arcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);arcPaint.setStyle(Paint.Style.FILL);arcPaint.setColor(Color.BLUE);RectF rectF = new RectF(20,620,200 ,820 );canvas.drawArc(rectF,0,90.0f,false,arcPaint);//绘制左上顶点为(20,820),右下顶点为(200,1020)的矩形内切椭圆从0度到90划过的圆弧区域端点连接椭圆几何中心所围成的封闭区域Paint arcPaint2 = new Paint(Paint.ANTI_ALIAS_FLAG);arcPaint2.setStyle(Paint.Style.FILL);arcPaint2.setColor(Color.BLUE);RectF rectF2 = new RectF(20,820,200 ,1020 );canvas.drawArc(rectF2,0,90.0f,true,arcPaint2);//绘制左上顶点为(20,1020),右下顶点为(200,1220)的矩形内切椭圆从0度到90划过的圆弧区域Paint arcStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);arcStrokePaint.setStyle(Paint.Style.STROKE);arcStrokePaint.setColor(Color.BLUE);RectF strokeRectF = new RectF(20,1020,200 ,1220 );canvas.drawArc(strokeRectF,0,90.0f,false,arcStrokePaint);//绘制左上顶点为(20,1220),右下顶点为(200,1420)的矩形内切椭圆从0度到90划过的圆弧区域端点连接椭圆几何中心所围成的线框区域Paint arcStrokePaint2 = new Paint(Paint.ANTI_ALIAS_FLAG);arcStrokePaint2.setStyle(Paint.Style.STROKE);arcStrokePaint2.setColor(Color.BLUE);RectF strokeRectF2 = new RectF(20,1220,200 ,1420 );canvas.drawArc(strokeRectF2,0,90.0f,true,arcStrokePaint);
这里需要注意的是sweepAngle的取值问题,其取值以顺时钟方向为正向,逆时钟方向为负向,具体参看下图:
//以400,130为左上顶点绘制bitmapPaint bitmapPaint = new Paint();//通过BitmapFactory获取bitmap对象Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pic);//调用canvas对象的drawBitmap方法绘制bitmapcanvas.drawBitmap(bitmap,400,130,bitmapPaint);//使用matrix绘制bitmap,这里通过matrix将bitmap宽高压缩到0.2*width,0.2*heightPaint matrixBitmapPaint = new Paint();Bitmap matrixBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pic);//新建Matrix对象Matrix matrix = new Matrix();//matrix对象应用缩放比matrix.postScale(0.2f,0.2f);canvas.drawBitmap(matrixBitmap,matrix,matrixBitmapPaint);
这里右侧的图片原始尺寸并不是没有绘制完,而是View内容超过了用户可视区域,此时就需要引入滚动处理了,我们在后续文章中再做介绍。
//绘制以(380,20)为左上顶点,(480,100)为右下顶点的内切填充椭圆Paint ovalPaint = new Paint(Paint.ANTI_ALIAS_FLAG);ovalPaint.setStyle(Paint.Style.FILL);ovalPaint.setColor(Color.RED);canvas.drawOval(380,20,480,100,ovalPaint);//绘制以(500,20)为左上顶点,(600,100)为右下顶点的内切椭圆线框Paint strokeOvalPaint = new Paint(Paint.ANTI_ALIAS_FLAG);strokeOvalPaint.setStyle(Paint.Style.STROKE);strokeOvalPaint.setColor(Color.RED);canvas.drawOval(500,20,600,100,strokeOvalPaint);
//以(120,400)为圆心,70为半径绘制填充圆Paint circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);circlePaint.setStyle(Paint.Style.FILL);circlePaint.setColor(Color.RED);canvas.drawCircle(120,400,70,circlePaint);//以(280,400)为圆心,70为半径绘制圆环Paint strokeCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);strokeCirclePaint.setStyle(Paint.Style.STROKE);strokeCirclePaint.setColor(Color.RED);canvas.drawCircle(280,400,70,strokeCirclePaint);
//以(20,160)为左上角,(220,260)为右下角,绘制一个矩形线框Paint strokeRectPaint = new Paint(Paint.ANTI_ALIAS_FLAG);strokeRectPaint.setStrokeWidth(10);//设置画笔样式为空心strokeRectPaint.setStyle(Paint.Style.STROKE);strokeRectPaint.setColor(Color.BLUE);//调用canvas对象的drawRect方法绘制矩形线框canvas.drawRect(20,160,220,260,strokeRectPaint);//以(20,270)为左上角,(220,300)为右下角,绘制一个填充矩形Paint rectPaint = new Paint(Paint.ANTI_ALIAS_FLAG);rectPaint.setStrokeWidth(10);//设置画笔样式为实心rectPaint.setStyle(Paint.Style.FILL);rectPaint.setColor(Color.BLUE);//调用canvas对象的drawRect方法绘制矩形线框canvas.drawRect(20,270,220,300,rectPaint);
从上述代码及运行效果可以看出,同样适用drawRect
方法进行矩形绘制,当画笔样式为Paint.Style.STROKE
,绘制出来是线框,当画笔类型为Paint.Style.FILL
,绘制出来为填充矩形。
drawRoundRect方法与drawRect使用方式相似,请大家自行尝试。
//使用线宽10,分别以(20,100),(20,120),(20,140)为起点,(180,100),(180,120,180,140)为终点绘制直线Paint linesPaint = new Paint(Paint.ANTI_ALIAS_FLAG);linesPaint.setStrokeWidth(10);linesPaint.setColor(Color.RED);//多条直线起终点的数据集,声明顺序为x1,y1,x2,y2,x3,y3,x4,y4...,每四个值构成一条直线float[] lines = {20,100,180,100,20,120,180,120,20,140,180,140};//调用canvas对象的drawLines方法绘制多条直线canvas.drawLines(lines,linesPaint);
//使用线宽10,以(20,80)为起点,(180,80)为终点绘制一条直线Paint linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);//设置画笔粗细,影响线宽linePaint.setStrokeWidth(10);//设置画笔颜色linePaint.setColor(Color.BLUE);//调用canvas对象的drawLine方法绘制直线canvas.drawLine(20,80,180,80,linePaint);
本文分享自微信公众号 - 小海编码日记(gh_1f87b8c00ede)。
转载地址:http://vqpei.baihongyu.com/