目录
前言
Android自定义控件经常会用到Canvas绘制2D图形,在优化自己自定义控件技能之前,必须熟练掌握Canvas绘图机制。本文从以下三个方面对Canvas绘图机制进行讲解:
- 画布Canvas
- 画笔Paint
- 示例圆形进度条
画布Canvas
首先,来看一下Android官网对Canvas类的定义:
The Canvas class holds the “draw” calls。To draw something, you need 4 basic components: A Bitmap to hold the pixels, a Canvas to host the draw calls(writing into the bitmap), a drawing primitive(eg, Rect, Path, text, Bitmap), and a paint(to describe the colors and styles for the drawing).
简单来说,Android进行2D绘图必须要有Canvas类的支持,它位于“android.graphics.Canvas”包下。我们可以把Canvas理解成系统分配给我们的一块用于绘图的内存(ps:真正的内存是其包含的Bitmap)。
Canvas提供了两个构造函数:
- Canvas() : 创建一个空的Canvas对象。
- Canvas(Bitmap bitmap) : 创建一个以bitmap位图为背景的Canvas。
通常,我们会采用第二种包含Bitmap参数的构造函数方式或者直接使用onDraw方法中系统提供的Canvas。
既然Canvas主要用于绘图,那么它提供了很多相应的draw方法,方便我们在Canvas对象上绘图,介绍几个常用的draw方法:
- void drawRect(RectF rect, Paint paint) : 绘制区域,参数为RectF的区域。
- void drawOval(RectF oval, Paint paint) : 绘制矩形的内切椭圆。
- void drawCircle(float cx, float cy, float radius, Paint paint) : 绘制圆形。cx和cy是圆心坐标,radius是半径长度。
- void drawArc(RectF oval, float startAngle, float sweepAngle. boolean useCenter, Paint paint) : 绘制圆弧形,也是以矩形的内切椭圆为标准。其中,startAngle为起始角度,sweepAngle为弧度大小,useCenter为true,则是绘制一个扇行,为false,则只是一段圆弧。(ps:startAngle为0时,是圆形钟表3点钟方向)。
- void drawPath(Path path, Paint paint) : 根据给定的path,绘制连线。
- void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) : 贴图,参数bitmap是要进行绘制的bitmap对象,参数src是指bitmap的源区域(一般为null),dst是bitmap的目标区域,paint是画笔,可为null。
- void drawLine(float startX, float startY, float stopX, float stopY, Paint paint) : 根据给定的起点和结束点之间绘制连线。
- void drawPoint(float x, float y, Paint paint) : 根据给定的坐标,绘制点。
- void drawText(String text, float x, float y, Paint paint) : 根据给定的坐标,绘制文字。其中,x是文本起始的x轴坐标,y是文本纵向结束的y轴坐标。
画笔Paint
从上面列举的几个Canvas.drawXXX()方法可以看到,其中都有一个类型为Paint的参数,可以把它理解成为”画笔”,通过这个画笔,在Canvas这张画布上作画。它位于“android.graphics.Paint”包下,主要用于设置绘图风格,包括画笔颜色。
Paint中提供了大量设置绘画风格的方法,这里仅列出一些常用的功能:
- setARGB(int a, int r, int g, int b) : 设置ARGB颜色。
- setColor(int color) : 设置颜色。
- setAlpha(int a) : 设置透明度。
- setAntiAlias(boolean aa) : 设置是否抗锯齿。
- setShader(Shader shader) : 设置Paint的填充效果。
- setStrokeWidth(float width) : 设置Paint的笔触宽度。
- setStyle(Paint.Style style) : 设置Paint的填充风格。
- setTextSize(float textSize) : 设置绘制文本时的文字大小。
自定义圆形进度条
这里以一个自定义的圆形进度条为例,我们首先看一下效果图:
通过效果图,我们首先抽象出自定义属性,如下:
- 圆环内部填充色。
- 圆环进度条的背景色。
- 圆环进度条的颜色。
- 圆环半径。
- 圆环进度条的宽度。
- 进度条起始的角度。
- 中间文字的颜色。
- 中间文字的大小。
- 中间文字是否需要显示的标志位。
在Android中,可以在项目的res/values/目录下,建立一个resources源文件,通过declare-styleable来声明一个特定的属性集合。
示例属性集合如下所示(res/values/attrs_round_progress_bar.xml):
<resources>
<declare-styleable name="RoundProgressBar">
<attr name="startAngle" format="integer"></attr>
<attr name="radius" format="dimension"></attr>
<attr