概述:
我们时常会遇到一些需要利用画图来实现的功能。例如一些常见的几何图形——点、直线、弧、圆、椭圆、文字、矩形、多边形、曲线、圆角矩形,总不能遇到 一个几何图形就用图片来代替吧。这样我们的手机肯定会吃不消。就算我们现在能够使用一些少量图片能够来解决当前的一些问题,可是对于那些“变化多端”的需求来说,这些手段根本不值一提。对此,我们可以利用Canvas画图技术来解决。下面就让我们一起来解开Canvas的神秘面纱吧。
示例编程:
1.绘制圆形
首先看一下效果图展示:
实现关键代码:
private void drawCirle(Canvas canvas) {
canvas.drawCircle(500, 500, 200, paint);
}
2.绘制弧线区域
效果图展示:
实现关键代码:
private void drawCuttingCirle(Canvas canvas) {
RectF rect = new RectF(0, 0, 400, 400);
canvas.drawArc(rect, // 弧线所使用的矩形区域大小
0, // 开始角度
90, // 扫过的角度
false, // 是否使用中心
paint);
}
3.绘制1/4圆
效果图展示:
实现关键代码:
private void drawQuarterCirle(Canvas canvas) {
RectF rect = new RectF(0, 0, 300, 300);
canvas.drawArc(rect, // 弧线所使用的矩形区域大小
0, // 开始角度
90, // 扫过的角度
true, // 是否使用中心
paint);
}
4.绘制直线
效果图展示:
实现关键代码:
private void drawLine(Canvas canvas) {
canvas.drawLine(10, 10, 800, 1000, paint);
}
5.绘制椭圆
效果图展示:
实现关键代码:
private void drawOval(Canvas canvas) {
// 定义一个矩形区域
RectF oval = new RectF(10, 5, 600, 900);
// 矩形区域内切椭圆
canvas.drawOval(oval, paint);
}
6.绘制矩形
效果图展示:
实现关键代码:
private void drawRect(Canvas canvas) {
RectF rect = new RectF(50, 50, 200, 200);
canvas.drawRect(rect, paint);
}
7.绘制圆角矩形
效果图展示:
实现关键代码:
private void drawSmoothRect(Canvas canvas) {
RectF rect = new RectF(50, 50, 200, 200);
canvas.drawRoundRect(rect, 30, // x轴的半径
30, // y轴的半径
paint);
}
8.绘制多边形
效果图展示:
实现关键代码:
private void drawPolygon(Canvas canvas) {
Path path = new Path(); // 定义一条路径
path.moveTo(10, 10); // 移动到 坐标10,10
path.lineTo(150, 1360);
path.lineTo(960, 720);
path.lineTo(500, 180);
path.lineTo(10, 10);
canvas.drawPath(path, paint);
}
9.绘制罗盘
效果图展示:
实现关键代码:
private void drawCompass(Canvas canvas) {
paint.setAntiAlias(true);
paint.setStyle(Style.STROKE);
canvas.translate(canvas.getWidth() / 2, 500); // 平移罗盘
canvas.drawCircle(0, 0, 200, paint); // 画圆圈
// 使用path绘制路径文字
canvas.save();
canvas.translate(-155, -155);
Path path = new Path();
path.addArc(new RectF(0, 0, 300, 300), -180, 180);
Paint citePaint = new Paint(paint);
citePaint.setTextSize(30);
citePaint.setStrokeWidth(1);
canvas.drawTextOnPath("http://blog.csdn.net/lemon_tree", path, 35, 0, citePaint);
canvas.restore();
Paint tmpPaint = new Paint(paint); // 小刻度画笔对象
tmpPaint.setStrokeWidth(2);
tmpPaint.setTextSize(30);
float y = 200;
int count = 60; // 总刻度数
for (int i = 0; i < count; i++) {
if (i % 5 == 0) {
canvas.drawLine(0f, y, 0, y + 20f, paint);
canvas.drawText(String.valueOf(i / 5 + 1), -4f, y + 55f, tmpPaint);
} else {
canvas.drawLine(0f, y, 0f, y + 15f, tmpPaint);
}
canvas.rotate(360 / count, 0f, 0f); // 旋转画纸
}
// 绘制指针
tmpPaint.setColor(Color.GRAY);
tmpPaint.setStrokeWidth(4);
canvas.drawCircle(0, 0, 20, tmpPaint);
tmpPaint.setStyle(Style.FILL);
tmpPaint.setColor(Color.YELLOW);
canvas.drawCircle(0, 0, 5, tmpPaint);
canvas.drawLine(0, 30, 0, -135, paint);
}
以上的代码中,我不知道大家看上去会不会感觉有一点乱,不过没关系,在下一篇博客中我会对这一块单独拿出来说一下。以自定义一个动态时钟为例详细说明这部分的内容,大家稍安勿躁。大家可以参看《Android UI编程进阶——使用SurfaceViewt和Canvas实现动态时钟》进行学习。
10.记录手指运动的路径
效果图展示:
实现关键代码:
这一部分的功能实现主要就是考虑三个部分:记录路径(这里单独拿一个变量来保存的原因是因为画图的时候会有一个重绘的过程,也就需要擦除后重绘,如果不保存以前的路径,这样就可能导致以前的路径不见了)、记录事件、绘制。
获得记录的路径:
private ArrayList<PointF> graphics = new ArrayList<PointF>();
触摸事件:
public boolean onTouchEvent(MotionEvent event) {
graphics.add(new PointF(event.getX(), event.getY()));
invalidate(); // 重新绘制区域
return true;
}
绘制:
private void drawFingerPath(Canvas canvas) {
for (PointF point : graphics) {
canvas.drawPoint(point.x, point.y, paint);
}
}
源码下载:
(注:源码中除了Canvas使用集合的示范外还有画曲线、正/余弦函数、SurfaceView的使用、心跳。PS:心跳示例需要点击屏幕才能触发)