1.简单介绍自定义View
创建一个简单的自定义View非常简单,创建自定义View类继承自View,提前创建好Paint对象,从写onDray()方法,然后在onDray()方法中绘制自己需要的图像即可。
例:绘制矩形
public class ViewDemo extends View {
private Paint mPaint = new Paint();
public ViewDemo(Context context) {
super(context);
}
public ViewDemo(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public ViewDemo(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
{
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(Color.RED);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawRect(200,100,800,600,mPaint);
}
}
2.Canvas(画布),Paint(画笔)
2.1 Paint(画笔 ),Paint工具类有几个常用方法。
1.Paint.setStyle(Style style)设置绘制模式
2.Paint.setColor(int color)设置颜色
3.Paint.setStrokeWidth(float width)设置线条宽度
4.Paint.setTextSize(float textSize)设置文字大小
5.Paint.setAntiAlias(boolean true)抗锯齿开关
3.Canvas 的部分drawXXX()方法
3.1 drawColor(Color color)
在整个绘制区域涂上指定颜色
例:
drawColor(Color.RED); 将整个图层涂黑
关于颜色:
1.
3.2 drawCircle(float centerX,float centerY,float readius,Paint paint)
画圆
例:
drawCircle(100,100,50,paint);
这里,还可以设置Paint的各种参数,调节颜色,样式等
3.2.1.paint.setColor(Color color);可以设置画笔的颜色
3.2.2.paint.setStyle(Paint.Stytle Style);设置画笔的样式
比如:
1.paint.setStyle(Paint.Style.STROKE);// 修改Paint为画线样式
drawCircle(100,100,50,paint);
Paint.Style 类为一个枚举类
Paint.Style,里面有三种样式--FILL STROKE FILL_AND_STROKE
1.FILL 填充模式
2.STROKE 画线模式
3.FILL_AND_STROKE 两种模式共用,既填充又画线
Paint.Style 默认为FILL
3.2.3.Paint.setStrokeWidth(float width)
如果Style的模式为STROKE 或者 FILL_AND_STROKE,那还可以设置画笔的宽度
3.2.4.抗锯齿
在绘制的时候,很可能需要设置抗锯齿来使得图形或者文字来使得边缘更加平滑。
1.Paint.setAntiAlias(boolean true)
2.Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
例:
附:如果未开启抗锯齿,则图片会出现毛边现象。
抗锯齿不一定适用于所有场景,锯齿现象的产生,是由于图形分辨率过低,导致人眼察觉出了画面中的像素颗粒而已。如果不开启抗锯齿,图形的边缘也已经完美的,而并不是一个粗略计算的粗糙版本。开启抗锯齿后,之所以会看上去图形的边缘更加平滑,是因为修改图形边缘处的像素颜色,从而使得图形在肉眼看起来有更加平滑的感觉。
注:抗锯齿,在大多数情况下都应该开启。
3.3 drawRect(float left,float top,float right,float bottom,Paint paint) 矩形
Left,top,right,bottom 是矩形四条边的坐标(简单理解就是左上角跟右下角两个点的坐标)
3.4 drawPoint(float x,float y,Paint paint) 画点
1.x,y是点的坐标。
2.点的大小是通过 paint.setStrokeWith(width)来设定。
3.点的形状可以通过paint.setStrokeCap(cap)来设定。
这个方法是设置线条端点的形状,端点有圆头(ROUND),平头(BUTT),方头(SQUARE)
3.5 drawPoints(……),可以批量画点
3.6 drawOval(float left,float top,float right,float bottom,Paint paint) 画椭圆
drawOval(RectF rect,Paint paint)也可以画椭圆
3.7 drawLine(float startX,float startY,float stopX,float stopY,Paint paint) 画线
startX , startY , stopX , stopY 分别是线的起点和终点坐标。
canvas.drawLine(200, 200, 800, 500, paint);
drawLines(float[] pts,int offset,int count,Paint paint)/drawLines(float[] pts,Paint paint) 画线(批量画线)
3.8 drawRoundRect(float left,float top,float right,float bottom,float rx,float ry,Paint paint)画圆角矩形
rx和ry是圆角的横向半径和纵向半径。
drawRoundRectF(RectF rect,float rx,float ry,Paint paint)
3.9 drawArc(float left,float top,float right,float bottom,float startAngle,float sweepAngle,boolean useCenter,Paint paint)绘制弧形或扇形
drawArc 是使用一个椭圆来描述弧形。
startAngle 是弧形的起始角度(x轴正向为0度,顺时针为正角度)
sweepAngle 是弧形滑过的角度。
userCenter 表示是否连接圆心。
4 路径
路径类似于我们用画笔画画,画笔所画出来的一段不间断的曲线就是路径
在Android中,Path 类就代表路径
在Canvas中绘制路径的方法:Canvas(Path path,Paint paint)
4.1 直接描述路径
addXXX() ---直接添加子图形
addCircle(float x,flaot y,float radius,Direction dir) 添加圆
x,y,radius 为圆心的位置,圆的半径,dir为画圆的路径的方向。
路径的方向:顺时针CCW,逆时针CW
添加椭圆:
addOval(float left, float top, float right, float bottom, Direction dir) / addOval(RectF oval, Direction dir)addRect(float left, float top, float right, float bottom, Direction dir)
添加矩形:
addRect(RectF rect, Direction dir)
添加圆角矩形:
addRoundRect(RectF rect, float rx, float ry, Direction dir) / addRoundRect(float left, float top, float right, float bottom, float rx, float ry, Direction dir) / addRoundRect(RectF rect, float[] radii, Direction dir) / addRoundRect(float left, float top, float right, float bottom, float[] radii, Direction dir)
添加另一个 Path:
addPath(Path path)
xxxTo ----画线
xxxTo() 只是添加一条直线,addXxx()方法是添加的一整个封闭图形。
lineTo(float x, float y) / rLineTo(float x, float y) 画直线
从当前位置到目标位置画一条直线,x,y为目标位置的坐标。
lineTo(float x, float y) x,y为绝对坐标
rLineTo(float x, float y) x,y为相对坐标(既上次调用画Path方法的终点既为下一个起点)
例:
paint.setStyle(Style.STROKE);
path.lineTo(100, 100); // 由当前位置 (0, 0) 向 (100, 100) 画一条直线
path.rLineTo(100, 0); // 由当前位置 (100, 100) 向正右方 100 像素的位置画一条直线
quadTo(float x1, float y1, float x2, float y2) / rQuadTo(float dx1, float dy1, float dx2, float dy2) 画二次贝塞尔曲线
二次贝塞尔曲线的起点就是当前位置,x1,y1 和 x2,y2 就是控制点和终点的坐标。quadTo()为绝对坐标,rQuadTo()为相对坐标
贝塞尔曲线:
贝塞尔曲线是几何上的一种曲线。他通过起点,控制点和终点来描述一种计算机图形学。
简单的说,就是他可以绘制圆滑漂亮的曲线。
cubicTo(float x1, float y1, float x2, float y2, float x3, float y3) / rCubicTo(float x1, float y1, float x2, float y2, float x3, float y3) 画三次贝塞尔曲线
moveTo(float x, float y) / rMoveTo(float x, float y) 移动到目标位置
moveTo()就是移动到图形起点。
arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo) / arcTo(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean forceMoveTo) / arcTo(RectF oval, float startAngle, float sweepAngle) 画弧形
arcTo() 用于画弧形,forceMoveTo 参数来控制画笔是否跟上一个图形相连接。
addArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle) / addArc(RectF oval, float startAngle, float sweepAngle)
画弧形。
addArc() 相当于使用forceMoveTo = true 的 arcTo();
close() 封闭当前子图形
4.2 辅助的设置或者计算
Path.setFillType(Path.FillType ft) 设置填充方式
FillType 的值有四个 WIDING 为默认值
其中 前缀带 INVERSE 的为相反版本
WINDING与EVEN_ODD
WINDING与EVEN_ODD原理
即 even-odd rule (奇偶原则):
对于平面中的任意一点,向任意方向射出一条射线,这条射线和图形相交的次数(相交才算,相切不算哦)如果是奇数,则这个点被认为在图形内部,是要被涂色的区域;如果是偶数,则这个点被认为在图形外部,是不被涂色的区域。还以左右相交的双圆为
例:
射线的方向无所谓,因为同一个点向任何地方射线,结果都是一样的。
从上图可以看出,射线每穿过图形中的一条线,内外状态就发生一次切换,这就是为什么 EVEN_ODD 是一个「交叉填充」的模式。
WINDING
在我们绘制任何图形的时候,都是有绘制方向的,WINDING,相当于我们
然后,同样是从平面中的点向任意方向射出一条射线,但计算规则不一样:以 0 为初始值,对于射线和图形的所有交点,遇到每个顺时针的交点(图形从射线的左边向右穿过)把结果加 1,遇到每个逆时针的交点(图形从射线的右边向左穿过)把结果减 1,最终把所有的交点都算上,得到的结果如果不是 0,则认为这个点在图形内部,是要被涂色的区域;如果是 0,则认为这个点在图形外部,是不被涂色的区域。
这里我们可以得出:INDING 确实是一个「全填充」的规则,但如果使用不同的方向来绘制图形,结果就不一样了。
4.3 drawBitmap(Bitmap bitmap, float left, float top, Paint paint) 画 Bitmap
重载方法
drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) /drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) /drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint)
4.4 drawText(String text, float x, float y, Paint paint) 绘制文字
X,y 为绘制的起始点