当我们实现更复杂的动画时,如nexus开机动画,前面的属性动画、容器动画就实现不了。
其实就是一个Path路径点的坐标追踪,可计算出指定路径的一些信息如总路长、指定长度所对应的坐标点;
要计算,肯定就需要和路径绑定:
两种方式:
PathMeasure pm=new PathMeasure();
pm.setPath(Path path,boolean forceClosed);
PathMeasure pm=new PathMeasure(Path path,boolean forceClosed);
常用函数:
public float getLength();
//我们知道,Path可以由多条曲线构成,但不管是getLength()、getSegment()还是其他函数都是计算其中一条线段。而该函数就是跳转到下一条曲线的函数;
//轮询得到的曲线与Path添加的顺序一致;
boolean nextContour();
//获取路径上某一长度的位置已经位置的正切值
// distance:距离该路径起始点的长度0<=diatance<=getLength
// pos:该点坐标,当前点在画布上的位置有两个值,x、y分别为pos[0]、pos[1]
// tan:该点的正切值;坐标系某点的正切值,即为远原点与该点连接起来,形成的夹角即为正切值y/x
boolean getPosTan(float distance,float[] pos,float tan)
//截取整个Path的某个片段,截取后的片段保存在dst中,最后一个 参数表示截取片段添加的到dst中,dst的起始点是否使用moveTo将路径的新起始点移动到结果Path的起始点,
重点讲解下该函数:
boolean getSegment(float startD,float stopD,Path dst,boolean startWithMoveTo)
截取路径的某个片段,将该片段路径***添加(注意:不是替换)***到dst路径中;
最后一个参数:决定在将截取的片段路径添加到dst中前,是否将dst的绘制起始点移动到添加片段路径的起始点;true:就会将路径起始点移动到添加路径的的起始点,这样被截取出来的片段路径保持原状;false:则会将路径的起始点改为上一条路径的终点,从而保证路径的延续性,新添加的路径起始点会被改变;
canvas.translate(100,100);
mPath.addRect(-50,-50,50,50, Path.Direction.CW);
Path dst = new Path();
dst.lineTo(100,100);
mPm.setPath(mPath,false);
mPm.getSegment(0,150,dst,false);
canvas.drawPath(dst,mPaint);
当我们改变getSegment()参数分别为true、false效果分别入下:
当startWithMoveTo为true,被截取的的Path片段会保持原状,为false会将截取出来的片段的起始点移动到dst的最后一个点,以保证dst的连续性;
借助PathMeasure的getSegment()函数以及前面的属性动画实现路径加载动画效果:
public SegmentView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(Color.RED);
mPaint.setStrokeWidth(5);
mPath = new Path();
mPm = new PathMeasure();
mPaint.setStyle(Paint.Style.STROKE);
mPath.addRect(-50,-50,50,50, Path.Direction.CW);
mPm.setPath(mPath,false);
ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
animator.setDuration(2000);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mFraction = (float) animation.getAnimatedValue();
invalidate();
}
});
animator.setRepeatCount(2);
animator.start();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.translate(100,100);
Path dst = new Path();
float stopD=mPm.getLength()*mFraction;
mPm.getSegment(0,stopD,dst,true);
canvas.drawPath(dst,mPaint);
}
nt(0,stopD,dst,true);
canvas.drawPath(dst,mPaint);
}
[外链图片转存中…(img-B17xm4eK-1575363727971)]