先来看一下最终效果!
简介:前面的文章里有介绍如何利用svg的相关方法来实现如图所示的矢量且可控制的Path动画,然而,虽然svg动画出来这么久了,前面的文章里也有提到,在有些低版本的api中,暂时还不支持用svg做path变化的动画,所以,这里介绍一种本人认为可以自己利用Path类来模拟一个svg的效果。
关键类
Path,PathMeasure,Canvas
实现步骤
1.首先需要知道要实现的完整的图像是什么样子的,也就是我图中的五角星形状:
Path star = new Path();
star.moveTo(100,100);
star.rLineTo(200,0);
star.lineTo(100,200);
star.lineTo(200,50);
star.lineTo(300,200);
star.close();
这样我的五角星就准备好了;
2.然后我们需要另外一个Path对象,用来存储我们裁剪之后的Path路径;
Path path2 = new Path();
3.然后我们要进行对五角星动画的裁剪,涉及到的方法是PathMeasure的getLength和getSegment方法,getLength()不用多说,就是用来获取path的总长度,getSegment是用来截取它其中的一部分,他的用法是:
boolean getSegment (float startD, float stopD, Path dst, boolean startWithMoveTo)
方法各个参数释义:
参数 | 作用 | 备注 |
---|---|---|
返回值(boolean) | 判断截取是否成功 true | 表示截取成功,结果存入dst中,false 截取失败,不会改变dst中内容 |
startD | 开始截取位置距离 | Path 起点的长度取值范围: 0 <= startD < stopD <= Path总长度 |
stopD | 结束截取位置距离 | Path 起点的长度取值范围: 0 <= startD < stopD <= Path总长度 |
dst | 截取的 Path 将会添加到 dst 中 | 注意: 是添加,而不是替换 |
startWithMoveTo | 起始点是否使用 moveTo | 用于保证截取的 Path 第一个点位置不变 |
4.完成裁剪,并实现动画过程:
final PathMeasure pathMeasure = new PathMeasure(star,true);
ObjectAnimator objectAnimator = new ObjectAnimator();
objectAnimator.setFloatValues(0,pathMeasure.getLength());
objectAnimator.setDuration(3000);
objectAnimator.setInterpolator(new AccelerateInterpolator());
objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
path2.reset(); //每次裁剪前先清空path2
pathMeasure.getSegment(0, (Float)animation.getAnimatedValue(),path2,true); //进行裁剪并存储
invalidate();
}
});
objectAnimator.setRepeatCount(-1);
objectAnimator.setRepeatMode(ValueAnimator.REVERSE);
objectAnimator.start();
5.最后一步,完成绘制,这一步就不用多说了,直接上代码:
canvas.drawPath(path2, paint);
到这里就全部完成了。