常用方法
1.moveTo(float x, float y)
移动下一次操作的起点位置
2.lineTo(float x, float y)
添加上一个点到当前点之间的直线到Path
3. close()
连接第一个点连接到最后一个点,形成一个闭合区域
4.addRect, addRoundRect, addOval, addCircle, addPath, addArc, arcTo
添加(矩形, 圆角矩形, 椭圆, 圆, 路径, 圆弧) 到当前Path
4.isEmpty()
判断Path是否为空
5.isRect()
判断path是否是一个矩形
6.set(@NonNull Path src)
用新的路径替换到当前路径所有内容
7.offset(float dx, float dy)/offset(float dx, float dy, @Nullable Path dst)
对当前路径之前的操作进行偏移
8.quadTo, cubicTo
分别为二次和三次贝塞尔曲线的方法
https://www.jianshu.com/p/582545122a7a
9.rMoveTo, rLineTo, rQuadTo, rCubicTo
不带r的方法是基于原点的坐标系(偏移量),rXxx方法是基于当前点坐标系(偏移量)
10.setFillType, getFillType, isInverseFillType, toggleInverseFillType
设置,获取,判断和切换填充模式
11.op
对两个Path进行布尔运算(即取交集、并集等操作)
12.computeBounds
计算Path的边界
13.reset, rewind
清除Path中的内容(reset相当于重置到new Path阶段,rewind会保留Path的数据结构)
14.transform
矩阵变换
PathMeasure
是一个用来测量Path的类
forceClosed就是Path最终是否需要闭合,如果为True的话,则不管关联的Path是否是闭合的,都会被闭合,forceClosed对绑定的Path不会产生任何影响
Path path = new Path();
path.lineTo(0, 200);
path.lineTo(200, 200);
path.lineTo(200, 0);
PathMeasure measure = new PathMeasure(path, forceClosed);
float length = measure.getLength();
getSegment
boolean getSegment (float startD, float stopD, Path dst, boolean startWithMoveTo)
这个API用于截取整个Path的片段,通过参数startD和stopD来控制截取的长度,并将截取的Path保存到dst中,最后一个参数startWithMoveTo表示起始点是否使用moveTo方法,通常为True,保证每次截取的Path片段都是正常的、完整的。
如果startWithMoveTo设置为false,通常是和dst一起使用,因为dst中保存的Path是被不断添加的,而不是每次被覆盖,设置为false,则新增的片段会从上一次Path终点开始计算,这样可以保存截取的Path片段数组连续起来。
由于硬件加速的问题,PathMeasure中的getSegment在讲Path添加到dst数组中时会被导致一些错误,需要通过mDst.lineTo(0,0)来避免这样一个Bug。
Path path = new Path();
path.addRect(-200, -200, 200, 200, Path.Direction.CW);
PathMeasure measure = new PathMeasure(path, false);
canvas.drawPath(path, paint);
Path dst = new Path();
dst.lineTo(-300, -300);
measure.getSegment(200, 600, dst , false);
paint.setColor(Color.GREEN);
canvas.drawPath(dst, paint);
路径绘制是PathMeasure最常用的功能,其原理就是通过getSegment来不断截取Path片段,从而不断绘制完整的路径
例如:
public class PathPainter extends View {
private Path mPath;
private Paint mPaint;
private PathMeasure mPathMeasure;
private float mAnimatorValue;
private Path mDst;
private float mLength;
public PathPainter(Context context) {
super(context);
}
public PathPainter(Context context, AttributeSet attrs) {
super(context, attrs);
mPathMeasure = new PathMeasure();
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(5);
mPath = new Path();
mPath.addCircle(400, 400, 100, Path.Direction.CW);
mPathMeasure.setPath(mPath, true);
mLength = mPathMeasure.getLength();
mDst = new Path();
final ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
mAnimatorValue = (float) valueAnimator.getAnimatedValue();
invalidate();
}
});
valueAnimator.setDuration(2000);
valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
valueAnimator.start();
}
public PathPainter(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mDst.reset();
// 硬件加速的BUG
mDst.lineTo(0,0);
float stop = mLength * mAnimatorValue;
mPathMeasure.getSegment(0, stop, mDst, true);
canvas.drawPath(mDst, mPaint);
}
}
同样的效果也可以用DashPathEffect来实现
nextContour
如果有一个Path,包含了多个Path,那么通过nextContour这个方法,就可以进行切换
Path path = new Path();
path.addRect(-200, -200, 200, 200, Path.Direction.CW);
path.addRect(-100, -100, 100, 100, Path.Direction.CW);
PathMeasure measure = new PathMeasure(path, false);
float length = measure.getLength();
boolean nextContour = measure.nextContour();
float length2 = measure.getLength();
getPosTan
这个方法是用于得到路径上某一长度的位置以及该位置的正切值的矩阵: POSITION_MATRIX_FLAG(位置) 返回值true表示成功,数据会存入matrix中,false 失败,matrix内容不会改变 PathEffect见文知意很明显就是路径效果的意思 可以使用圆角来代替尖锐的角从而对基本图形的形状尖锐的边角进行平滑 CornerPathEffect的构造方法只接受一个参数radius,意思就是转角处的圆滑程度 DashPathEffect来创建一个虚线的轮廓(短横线/小圆点),而不是使用实线。你还可以指定任意的虚/实线段的重复模式,第一个参数是一个浮点型的数组,那这个数组有什么意义呢?其实是这样的,我们在定义该参数的时候只要浮点型数组中元素个数大于等于2即可 float[] {20, 10}的偶数参数20(注意数组下标是从0开始哦)定义了我们第一条实线的长度,而奇数参数10则表示第一条虚线的长度,如果此时数组后面不再有数据则重复第一个数以此往复循环,比如我们20,10后没数了,那么整条线就成了[20,10,20,10,20,10…………………………]这么一个状态,DashPathEffect的第二个参数我称之为偏移值,动态改变其值会让路径产生动画的效果 这种效果可以定义一个新的形状(路径)并将其用作原始路径的轮廓标记。 将两种效果组合起来应用,先使用第一种效果,然后在这种效果的基础上应用第二种效果。 顺序地在一条路径中添加两种效果,这样每一种效果都可以应用到原始路径中,而且两种结果可以结合起来。boolean getPosTan (float distance, float[] pos, float[] tan)
通过指定distance(0Path path = new Path();
path.addCircle(0, 0, 300, Path.Direction.CW);
PathMeasure measure = new PathMeasure(path, false);
float[] pos = new float[2];
float[] tan = new float[2];
measure.getPosTan(measure.getLength()/4, pos , tan );
//获取切点角度
float degrees = (float) (Math.atan2(tan[1], tan[0]) * 180.0 / Math.PI);
getMatrix
boolean getMatrix (float distance, Matrix matrix, int flags)
最后一个参数规定哪些内容会存入到matrix中,可选择:
ANGENT_MATRIX_FLAG(正切)PathEffect
CornerPathEffect
mEffects[1] = new CornerPathEffect(50);
DashPathEffect
mEffects[3] = new DashPathEffect(new float[] {20, 10}, mPhase);
PathDashPathEffect
ComposePathEffect
SumPathEffect