在 Android 自定义控件中,如果继承 View,需要进行绘图,就需要用到 Canvas 。Canvas 称为画布,能够在上面绘制各种东西,是 Android 平台 2D 图形绘制的基础。当创建自定义View类时候,继承 View,就可以重写方法 onDraw(),在方法中的参数就是 Canvas 对象:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
1. Canvas 的常用API
操作类型 | 相关API | 备注 |
---|---|---|
绘制颜色 | drawColor, drawRGB, drawARGB | 使用单一颜色填充整个画布 |
绘制基本形状 | drawPoint, drawPoints, drawLine, drawLines, drawRect, drawRoundRect, drawOval, drawCircle, drawArc | 依次为 点、线、矩形、圆角矩形、椭圆、圆、圆弧 |
绘制图片 | drawBitmap, drawPicture | 绘制位图和图片 |
绘制文本 | drawText, drawPosText, drawTextOnPath | 依次为 绘制文字、绘制文字时指定每个文字位置、根据路径绘制文字 |
绘制路径 | drawPath | 绘制路径,绘制贝塞尔曲线时也需要用到该函数 |
顶点操作 | drawVertices, drawBitmapMesh | 通过对顶点操作可以使图像形变,drawVertices直接对画布作用、 drawBitmapMesh只对绘制的Bitmap作用 |
画布剪裁 | clipPath, clipRect | 设置画布的显示区域 |
画布快照 | save, restore, saveLayerXxx, restoreToCount, getSaveCount | 依次为 保存当前状态、 回滚到上一次保存的状态、 保存图层状态、 回滚到指定状态、 获取保存次数 |
画布变换 | translate, scale, rotate, skew | 依次为 位移、缩放、 旋转、错切 |
Matrix(矩阵) | getMatrix, setMatrix, concat | 实际上画布的位移,缩放等操作的都是图像矩阵Matrix, 只不过Matrix比较难以理解和使用,故封装了一些常用的方法。 |
更多更详细的方法,可以参考官方文档:
https://developer.android.google.cn/reference/android/graphics/Canvas?hl=en
2. Canvas API 操作
2.1 绘制颜色
用于给整个画布填充颜色,用于绘制底色。
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.parseColor("#dcdcdc"));
}
效果:
2.2 绘制基本形状
2.2.1 drawPoint,drawPoints
这两个方法用于画单个点以及一组的点:
void | drawPoint(float x, float y, Paint paint) Helper for drawPoints() for drawing a single point. |
void | drawPoints(float[] pts, Paint paint) Helper for drawPoints() that assumes you want to draw the entire array |
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.parseColor("#dcdcdc"));
canvas.drawPoint(200, 200, mPaint);// 控件的左上角为原点(0,0),x,y的单位为px
//一组坐标点
float[] points = {50, 250, 100, 250, 150, 250, 200, 250, 250, 250, 300, 250};
canvas.drawPoints(points, mPaint);
}
效果:
2.2.2 drawLine, drawLines
这两个方法用于画单条直线以及一组的直线:
void | drawLine(float startX, float startY, float stopX, float stopY, Paintpaint) Draw a line segment with the specified start and stop x,y coordinates, using the specified paint. |
void | drawLines(float[] pts, Paint paint) |
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.parseColor("#dcdcdc"));
//两点确定一条直线
canvas.drawLine(0, 0, 200, 200, mPaint);
float[] lines = {0, 100, 200, 100, 0, 300, 300, 300};
canvas.drawLines(lines, mPaint);
}
效果:
2.2.3 drawRect,drawRoundRect
这两个方法用于画矩形以及圆角矩形,要确定一个矩形,需要的是:左,上,右,底的位置。
void | drawRect(float left, float top, float right, float bottom, Paint paint) Draw the specified Rect using the specified paint. |
void | drawRect(Rect r, Paint paint) Draw the specified Rect using the specified Paint. |
void | drawRect(RectF rect, Paint paint) Draw the specified Rect using the specified paint. |
void | drawRoundRect(RectF rect, float rx, float ry, Paint paint) Draw the specified round-rect using the specified paint. |
void | drawRoundRect(float left, float top, float right, float bottom, float rx,float ry, Paint paint) Draw the specified round-rect using the specified paint. |
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.parseColor("#dcdcdc"));
Rect rect = new Rect(0, 0, 50, 100);
canvas.drawRect(rect, mPaint);
RectF rectRound = new RectF(30, 150, 300, 400);
canvas.drawRoundRect(rectRound, 30, 30, mPaint);
}
Rect是int(整形)的,而RectF是float(单精度浮点型)。
效果:
2.2.4 drawOval
用于画椭圆,具体的方法为:
void | drawOval(float left, float top, float right, float bottom, Paint paint) Draw the specified oval using the specified paint. |
void | drawOval(RectF oval, Paint paint) Draw the specified oval using the specified paint. |
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.parseColor("#dcdcdc"));
RectF rect = new RectF(30, 150, 500, 300);
canvas.drawOval(rect, mPaint);
}
效果:
2.2.5 drawCircle, drawArc
用于画圆形和圆弧,具体方法如下:
void | drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean useCenter, Paint paint)
Draw the specified arc, which will be scaled to fit inside the specified oval. |
void | drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter,Paint paint)
Draw the specified arc, which will be scaled to fit inside the specified oval. |
void | drawCircle(float cx, float cy, float radius, Paint paint) Draw the specified circle using the specified paint. |
画圆:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.parseColor("#dcdcdc"));
//画圆,圆心的位置以及半径就能确定一个圆
canvas.drawCircle(150, 150, 100, mPaint);
}
效果:
画圆弧:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.parseColor("#dcdcdc"));
//画椭圆
RectF rectF = new RectF(0, 0, 300, 300);
canvas.drawArc(rectF, 90, 90, false, mPaint);
}
效果:
2.3 绘制图片
2.3.1 drawBitmap
void | drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) Draw the specified bitmap, scaling/translating automatically to fill the destination rectangle. |
void | drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) Draw the specified bitmap, scaling/translating automatically to fill the destination rectangle. |
src 代表要绘制的bitmap 区域,dst 代表的是要将bitmap 绘制在屏幕的什么地方:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.parseColor("#dcdcdc"));
Rect rectSrc = new Rect(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
RectF rectFDis = new RectF(0, 0, getWidth(), getHeight());
canvas.drawBitmap(mBitmap, rectSrc, rectFDis, mPaint);
}
结果:
void | drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) Draw the bitmap using the specified matrix. |
将图片进行缩小一半后,显示在画布上:
mMatrix = new Matrix();
mMatrix.postScale(0.5f,0.5f);
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.parseColor("#dcdcdc"));
canvas.drawBitmap(mBitmap,mMatrix,mPaint);
}
效果:
2.4 绘制文本
2.4.1 drawText
void | drawText(String text, float x, float y, Paint paint) Draw the text, with origin at (x,y), using the specified paint. |
用于将字符串写在指定起始位置
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.parseColor("#dcdcdc"));
canvas.drawText("鹭岛猥琐男",100,200,mPaint);
}
效果:
参考:
https://www.gcssloop.com/customview/Canvas_BasicGraphics
https://developer.android.google.cn/reference/android/graphics/Canvas?hl=en