记录下自己学习自定义View的过程。共勉
首先,在我们创建的自定义View中 重写onDraw()方法。如下
@Overrideprotected void onDraw(Canvas canvas){
super.onDraw(canvas);
}
我们知道,自定义View需要画笔和画布。在onDraw()方法中,参数canves就是我们所需要的画布,对于画笔,我们需要自己创建一下
Paint paint = new Paint();
这两样东西都创建好了之后,就可以开始绘制了。
一、Canves.drawXXX
我们先来看一下Canves的一些常用方法
Canvas.drawColor(@ColorInt int color) 颜色填充
这是最基本的方法,例如 drawColor(Color.BLACK) 会把整个区域染成纯黑色,覆盖掉原有内容;
drawColor(Color.parse("#FF0000") 会把整个区域染成红色
当然也有其他颜色方法,如drawRGB(int r, int g, int b) 和 drawARGB(int a, int r, int g, int b)方法。
drawCircle(float centerX, float centerY, float radius, Paint paint) 画圆
画圆方法有四个参数。前两个参数代表了圆的圆心坐标,radius代表半径,paint代表我们的画笔工具。
canvas.drawCircle(300,300,200, paint);
上述代码即为画一个圆心在(300,300)位置,半径为200的圆形。
在这里我们需要注意,Android的坐标系和我们在数学上学的坐标系有区别。如下图所示
drawRect(float left, float top, float right, float bottom, Paint paint) 画矩形
对于上面这个方法,前面四个参数是矩形四条边的坐标。
canvas.drawRect(100, 100, 500, 500, paint);
除此之外,还有以下重载方法
我们可以创建Rect对象或者RectF对象,来完成此方法。
那么有人可能会问,这两个东西有啥区别啊?其实,这两个都可以描述矩形,只是他们的参数的单位不同。
Rect参数的单位是int,而RectF参数的单位则是float。因此RectF的精度会比Rect准确那么一丢丢。
drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, Paint paint) 画圆角矩形
四个参数left, top, right, bottom 是四条边的坐标,rx 和 ry 是圆角的横向半径和纵向半径
canvas.drawRoundRect(100, 100, 500, 300, 50, 50, paint);
就是长这样的
drawPoint(float x, float y, Paint paint) 画点
x 和 y 是点的坐标。
canvas.drawPoint(50, 50, paint);
drawOval(float left, float top, float right, float bottom, Paint paint) 画椭圆
四个参数left, top, right, bottom 是这个椭圆的左、上、右、下四个边界点的坐标。
canvas.drawOval(50, 50, 700, 200, paint);
另外,它还有一个重载方法 drawOval(RectF rect, Paint paint),你可以直接填写 RectF 来绘制椭圆。
drawLine(float startX, float startY, float stopX, float stopY, Paint paint) 画线
startX, startY, stopX, stopY 分别是线的起点和终点坐标。
canvas.drawLine(200, 200, 800, 500, paint);
drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean useCenter, Paint paint) 绘制弧形或扇形
drawArc() 是使用一个椭圆来描述弧形的。left, top, right, bottom 描述的是这个弧形所在的椭圆。startAngle是弧形的起始角度,就是我们上面坐标系中的x轴正方向,是0度。顺时针绘制为正角度,逆时针则是负角度。sweepAngle是矩形划过的角度。useCenter代表是否连接到圆心,他也就代表的你要绘制的图形是扇形还是一个弧形。如果连接到圆心,那么就是扇形,反之则是一个弧形。
canvas.drawArc(100, 100, 700, 500, -135, 135, true, paint); //绘制扇形
paint.setStyle(Paint.Style.STROKE);
canvas.drawArc(100, 100, 700, 500, 90, 135, false, paint); //绘制弧形
drawBitmap(Bitmap bitmap, float left, float top, Paint paint) 画 Bitmap
以上就是Canves绘制基本图形的一些方法。接下来我们了解一下Paint画笔的方法。
二、Paint
paint.setColor(int color)
这个方法是给画笔设置颜色,比如你想画一个带颜色的圆,你需要这么做
paint.setColor(Color.RED); // 设置为红色
canvas.drawCircle(300, 300, 200, paint);
这样你画出来的圆就是一个红色的了。
paint.setStyle(Paint.Style style)
这个方法是设置画笔的style。这个Style是个枚举,里面包含FILL,STROKE,FILL_AND_STROKE三种类型。
STROKE代表画线,你看个图就懂了。
paint.setStyle(Paint.Style.STROKE);
canvas.drawCircle(300, 300, 200, paint);
paint.setStrokeWidth(float width)
如果你设置style为STROKE 和 FILL_AND_STROKE,则可以使用此方法。意思为设置线的宽度。
paint.setAntiAlias()
此方法意为开启抗锯齿。当然,你也可以使用这种方式来开启抗锯齿。在初始化画笔的时候使用。
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
了解了canves基本图形的画法和paint的一些常用方法,我们来了解一下drawPath()方法
三、canves.drawPath()
addCircle(float x, float y, float radius, Direction dir) 添加圆
x,y,radius是圆的基本参数,最后一个参数dir代表画圆的路径的方向。
方向分为两种,一种是CW,即顺时针,另外一种是CCW,逆时针。平时我们画圆,使用哪种都可以。但是涉及到图形相交的时候,我们需要考虑下使用哪种方向。
path.addCircle(300, 300, 200, Path.Direction.CW);
canvas.drawPath(path, paint);
你会发现,这样画出的效果和我们刚才使用canves,drawCircle()方法绘制出的效果是一样的。所以说如果只是想画一个圆,使用drawCircle()方法更方便。
其他一些方法,比如addRect(),addOval(),addOval()效果都一样的。
lineTo(float x, float y)
rLineTo(float x, float y) 画直线
这是一个画直线的方法,x,y是目标位置的坐标。初始坐标为(0,0)
lineTo(x,y)的参数是绝对坐标,rLineto则是相对坐标,就是相对于上次移动之后的那个点的坐标。看下图就明白了。、
path.lineTo(300, 300); // 由当前位置 (0, 0) 向 (300, 300) 画一条直线
path.lineTo(300, 0); // 由当前位置 (300, 300) 向正右方 300 像素的位置画一条直线
moveTo(float x, float y) 移动到目标位置
path.moveTo(200,100); // 将坐标位置移动到(200,100)
arcTo(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean forceMoveTo) 画弧形
这个方法和 drawArc() 比起来,少了一个参数 useCenter,说明这个方法只画弧形,不画扇形;而多了一个参数 forceMoveTo的意思是 绘制是要「抬一下笔移动过去」,还是「直接拖着笔过去」,区别在于是否留下移动的痕迹。froceMoveTo为true代表强制移动过去,也就是没有痕迹,反之则有痕迹。还是看图
addArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle)
这个方法也是画弧形的方法。 只不过这个方法没有forceMoveTo,在内部设置了forceMoveTo = true。是arcTo的简化版。
close() 封闭当前子图形
它的作用是把当前的子图形封闭,即由当前位置向当前子图形的起点绘制一条直线。因此,close() 和 lineTo(起点坐标) 是完全等价的。