网络测速全解析之一:自定义View基础知识(四)

一、Path之贝塞尔曲线(非常重要~

常用速查表:

为了兼容性(偷懒) 本表格中去除了在API21(即安卓版本5.0)以上才添加的方法。忍不住吐槽一下,为啥看起来有些顺手就能写的重载方法要等到API21才添加上啊。宝宝此刻内心也是崩溃的。

作用 相关方法 备注
移动起点 moveTo 移动下一次操作的起点位置
设置终点 setLastPoint 重置当前path中最后一个点位置,如果在绘制之前调用,效果和moveTo相同
连接直线 lineTo 添加上一个点到当前点之间的直线到Path
闭合路径 close 连接第一个点连接到最后一个点,形成一个闭合区域
添加内容 addRect, addRoundRect, addOval, addCircle, addPath, addArc, arcTo 添加(矩形, 圆角矩形, 椭圆, 圆, 路径, 圆弧) 到当前Path (注意addArc和arcTo的区别)
是否为空 isEmpty 判断Path是否为空
是否为矩形 isRect 判断path是否是一个矩形
替换路径 set 用新的路径替换到当前路径所有内容
偏移路径 offset 对当前路径之前的操作进行偏移(不会影响之后的操作)
贝塞尔曲线 quadTo, cubicTo 分别为二次和三次贝塞尔曲线的方法
rXxx方法 rMoveTo, rLineTo, rQuadTo, rCubicTo 不带r的方法是基于原点的坐标系(偏移量), rXxx方法是基于当前点坐标系(偏移量)
填充模式 setFillType, getFillType, isInverseFillType, toggleInverseFillType 设置,获取,判断和切换填充模式
提示方法 incReserve 提示Path还有多少个点等待加入(这个方法貌似会让Path优化存储结构)
布尔操作(API19) op 对两个Path进行布尔运算(即取交集、并集等操作)
计算边界 computeBounds 计算Path的边界
重置路径 reset, rewind

清除Path中的内容

reset不保留内部数据结构,但会保留FillType.

rewind会保留内部的数据结构,但不保留FillType

矩阵操作 transform 矩阵变换

第一步.理解贝塞尔曲线的原理:

贝塞尔曲线是用一系列点来控制曲线状态的

一阶曲线原理:(其实就是lineTo())

网络测速全解析之一:自定义View基础知识(四)_第1张图片

 

二阶曲线原理:

网络测速全解析之一:自定义View基础知识(四)_第2张图片

网络测速全解析之一:自定义View基础知识(四)_第3张图片

网络测速全解析之一:自定义View基础知识(四)_第4张图片

三阶曲线原理:

网络测速全解析之一:自定义View基础知识(四)_第5张图片

cubicTo

 

二、二阶曲线讲解:

网络测速全解析之一:自定义View基础知识(四)_第6张图片

public class Bezier extends View {

private Paint mPaint;
private int centerX, centerY;

private PointF start, end, control;

public Bessel1(Context context) {
super(context);
mPaint = new Paint();
mPaint.setColor(Color.BLACK);
mPaint.setStrokeWidth(8);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setTextSize(60);

start = new PointF(0,0); //数据点一
end = new PointF(0,0);  //数据点二
control = new PointF(0,0);  //控制点一
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
centerX = w/2;
centerY = h/2;

// 初始化数据点和控制点的位置
start.x = centerX-200;
start.y = centerY;
end.x = centerX+200;
end.y = centerY;
control.x = centerX;
control.y = centerY-100;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
// 根据触摸位置更新控制点,并提示重绘
control.x = event.getX();
control.y = event.getY();
invalidate();
return true;
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);

// 绘制数据点和控制点
mPaint.setColor(Color.GRAY);
mPaint.setStrokeWidth(20);
canvas.drawPoint(start.x,start.y,mPaint);
canvas.drawPoint(end.x,end.y,mPaint);
canvas.drawPoint(control.x,control.y,mPaint);

// 绘制辅助线
mPaint.setStrokeWidth(4);
canvas.drawLine(start.x,start.y,control.x,control.y,mPaint);
canvas.drawLine(end.x,end.y,control.x,control.y,mPaint);

// 绘制贝塞尔曲线
mPaint.setColor(Color.RED);
mPaint.setStrokeWidth(8);

Path path = new Path();

path.moveTo(start.x,start.y);
path.quadTo(control.x,control.y,end.x,end.y);

canvas.drawPath(path, mPaint);
}
}

三阶曲线:

有两个数据点和两个控制点控制曲线状态

网络测速全解析之一:自定义View基础知识(四)_第7张图片

public class Bezier2 extends View {

private Paint mPaint;
private int centerX, centerY;

private PointF start, end, control1, control2;
private boolean mode = true;

public Bezier2(Context context) {
this(context, null);

}

public Bezier2(Context context, AttributeSet attrs) {
super(context, attrs);

mPaint = new Paint();
mPaint.setColor(Color.BLACK);
mPaint.setStrokeWidth(8);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setTextSize(60);

start = new PointF(0, 0);
end = new PointF(0, 0);
control1 = new PointF(0, 0);
control2 = new PointF(0, 0);
}

public void setMode(boolean mode) {
this.mode = mode;
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
centerX = w / 2;
centerY = h / 2;

// 初始化数据点和控制点的位置
start.x = centerX - 200;
start.y = centerY;
end.x = centerX + 200;
end.y = centerY;
control1.x = centerX;
control1.y = centerY - 100;
control2.x = centerX;
control2.y = centerY - 100;

}

@Override
public boolean onTouchEvent(MotionEvent event) {
// 根据触摸位置更新控制点,并提示重绘
if (mode) {
control1.x = event.getX();
control1.y = event.getY();
} else {
control2.x = event.getX();
control2.y = event.getY();
}
invalidate();
return true;
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//drawCoordinateSystem(canvas);

// 绘制数据点和控制点
mPaint.setColor(Color.GRAY);
mPaint.setStrokeWidth(20);
canvas.drawPoint(start.x, start.y, mPaint);
canvas.drawPoint(end.x, end.y, mPaint);
canvas.drawPoint(control1.x, control1.y, mPaint);
canvas.drawPoint(control2.x, control2.y, mPaint);

// 绘制辅助线
mPaint.setStrokeWidth(4);
canvas.drawLine(start.x, start.y, control1.x, control1.y, mPaint);
canvas.drawLine(control1.x, control1.y,control2.x, control2.y, mPaint);
canvas.drawLine(control2.x, control2.y,end.x, end.y, mPaint);

// 绘制贝塞尔曲线
mPaint.setColor(Color.RED);
mPaint.setStrokeWidth(8);

Path path = new Path();

path.moveTo(start.x, start.y);
path.cubicTo(control1.x, control1.y, control2.x,control2.y, end.x, end.y);

canvas.drawPath(path, mPaint);
}
}

 

你可能感兴趣的:(android知识类)