一:Canvas.drawxxx()系列方法以及Paint常见使用
1:移动坐标系
canvas.translate(width/2,height/2); //可以将坐标系从左上角移动到指定位置
cavas.scale(1,-1);//反转y坐标轴,反转之后向上为正,向下为负。
2:drawRect(float left, float top, float right, float bottom, Paint paint)
画矩形传入的是左上点和右下点的坐标。drawRect(左上x,左上y,右下x,右下y,paint);
3:drawPoint(float x, float y, Paint paint)
在画点的时候,需要paint.setStrokeWidth();不然点看不到。
(1):画多个点
float [] pts={30,100,100,100,170,100,240,100,310,100};
private void init() {
paint=new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.parseColor("#2bb8ed"));
paint.setStrokeWidth(50);
paint.setStrokeCap(Paint.Cap.ROUND);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawPoints(pts,paint);
// canvas.drawPoints(pts,2,6,paint);
}
(2):画多个点同时偏移
float [] pts={30,100,100,100,170,100,240,100,310,100};
private void init() {
paint=new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.parseColor("#2bb8ed"));
paint.setStrokeWidth(50);
paint.setStrokeCap(Paint.Cap.ROUND);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// canvas.drawPoints(pts,paint);
canvas.drawPoints(pts,2,6,paint);
}
使用的数组还是之前的数组,就是在drawPoints的参数上做了调整。该方法第二个参数表示从第几个数组元素开始绘制,由于数组的元素是两个点构成一个坐标,因此偏移两个位置,即一个点。第三个参数表示一共使用几个数组元素,在本段代码中最后将原始数组进行了截取,相当于使用了下面这个新数组进行绘制。
float [] pts={100,100,170,100,240,100};
如果我们将参数调整为
canvas.drawPoints(pts,1,7,paint);
将会显示如下,虽然取了7个元素,但是最后一个元素没有配对的y坐标,无法绘制出来。
4:drawOval(float left, float top, float right, float bottom, @NonNull Paint paint);
前两个参数可以认为是椭圆外切矩形的左上点坐标。
接下来的两个参数可以认为是椭圆外切矩形的右下点坐标。
5:画线drawLine(float startX, float startY, float stopX, float stopY,@NonNull Paint paint)
我们通过代码画了三条线,分别设置了不同的Cap,三条线除了颜色不一样和cap不一样之外,其他的都一致。
private void init() {
paint=new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.RED);
paint.setStrokeWidth(50);
paint.setStrokeCap(Paint.Cap.BUTT);
paint1=new Paint(Paint.ANTI_ALIAS_FLAG);
paint1.setColor(Color.GRAY);
paint1.setStrokeWidth(50);
paint1.setStrokeCap(Paint.Cap.ROUND);
paint2=new Paint(Paint.ANTI_ALIAS_FLAG);
paint2.setColor(Color.BLUE);
paint2.setStrokeWidth(50);
paint2.setStrokeCap(Paint.Cap.SQUARE);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawLine(30,30,30,630,paint);
canvas.drawLine(130,30,130,630,paint1);
canvas.drawLine(230,30,230,630,paint2);
}
但是从效果图中,我们看到的三条线的长度好像并不一致。从代码中我们知道我们设置的起始点y坐标是30,但是只有第一条线满足了,后面两条线不满足,长度为600,也只有第一条满足了,后面两条未满足。因为cap是指当画笔画完之后,再给任务画一个帽子,这个帽子是多出来的。
和cap类似的还有一个join
public enum Join {
/**
* The outer edges of a join meet at a sharp angle
*/
MITER (0),
/**
* The outer edges of a join meet in a circular arc.
*/
ROUND (1),
/**
* The outer edges of a join meet with a straight line
*/
BEVEL (2);
private Join(int nativeInt) {
this.nativeInt = nativeInt;
}
final int nativeInt;
}
6:drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, Paint paint)
圆角矩形
7:drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean useCenter, Paint paint)
扇形或者弧形或者弧线。是否填充全在于paint.setStyle(Paint.Style.);
三点钟方向为0度。
顺时针为正方向。
useCenter表示在两边是否用线连接到圆心。如果连接就是弧形,不连接就是扇形。
private void init() {
paint=new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.RED);
paint.setStrokeWidth(10);
paint.setStrokeCap(Paint.Cap.BUTT);
paint.setStyle(Paint.Style.STROKE);
paint1=new Paint(Paint.ANTI_ALIAS_FLAG);
paint1.setColor(Color.GRAY);
paint1.setStrokeWidth(50);
paint1.setStrokeCap(Paint.Cap.ROUND);
paint2=new Paint(Paint.ANTI_ALIAS_FLAG);
paint2.setColor(Color.BLUE);
paint2.setStrokeWidth(10);
paint2.setStrokeCap(Paint.Cap.SQUARE);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawArc(0, 0, 200, 200, 50, 100, false, paint);
canvas.drawArc(0, 200, 300, 400, -360, 100, true, paint);
canvas.drawArc(0, 500, 400, 700, -150, 100, false, paint1);
canvas.drawArc(400, 500, 500, 600, -150, 100, true, paint1);
}
8:drawPath
path有两种方法,一类是直接描述路径,一类是辅助设置或计算
(1):addCircle/addOval/addArc/addRect/addRoundRect。
最后一个参数dir表示方向,有两个选项,一个是cr顺时针,一个是ccr逆时针。
lineTo/rLineTo 前者是绝对坐标。后者是相对坐标。都是画直线。
使用path画粗线的时候,比如直方图的粗线,一定要把style设置为stroke。
画线的方向就是方向。
quadTo/rQuadTo 画二次贝塞尔曲线。
cubicTo/rCubicTo 画三次贝塞尔曲线
moveTo/rMoveTo 移动到目标位置开始画起点
moveTo :移动到下一次操作的起点位置
setLastPoint 设置之前操作的最后一个点位置。这会取消之前的终点位置。如图所示:
那么在3d旋转的时候,能不能通过setLastPoint来旋转一个点达到效果呢?
重点
arcTo 只画弧形不画扇形。forceMoveTo参数表示是否留下画笔的移动痕迹。
addArc()表示forceMoveTo=true的简化版arcTo。
close()封闭当前图形。终点到起点的连线。当画笔为fill的时候,会自动封闭。
在画心形的时候,不要抬笔,也就是不要将forceMoveTo设置为true,因为true就以为着是一个新的If true, always begin a new contour with the arc。那么在封闭的时候,只能封闭当前的contour,而不能封闭之前的contour了。
path.arcTo(200,100,400,300,150, 210,false);
path.arcTo(400,100,600,300,180, 210,false);
path.lineTo(400, 442);
(2):辅助设置或计算 Path.setFillType(Path.FillType ft)
参考:
gcsSloop的博客
Hencoder的博客