PathMeasure

来源:互联网 发布:php收银系统 编辑:程序博客网 时间:2024/06/05 08:26

PathMeasure可用来画一些路径动画

比如这个搜索动画

下面看一下如何实现


先用path构造图形,分成两个path,里面的放大镜和外面的圆

path1 = new Path();path1.addArc(100,100,300,300,44,359.9f);path2 = new Path();path2.addArc(150,150,250,250,45,359.9f);path2.lineTo((float) (200 + 85 * Math.sin(45)),(float) (200 + 85 * Math.sin(45)));

再创建PathMeasure对象,并与path相关联

pathMeasure = new PathMeasure(path1,false);pathMeasure2 = new PathMeasure(path2,false);

pathmeasure主要用到这两个函数

getLength()

Return the total length of the current contour, or 0 if no path is associated with this measure object.

getLength()返回路径即该pathMeasure相关联的path的长度

getSegment(float startD, float stopD, Path dst, boolean startWithMoveTo)

Given a start and stop distance, return in dst the intervening segment(s).

getSegment()函数可返回一个路径片段,第一个参数是路径的起点,第二个参数是路径的重点,第三个参数是返回的路径片段,第四个参数是

是否从起点开始,一般都是true


然后创建ValueAnimator

animator = ValueAnimator.ofFloat(0,1);animator.setDuration(800);animator.setInterpolator(new AccelerateDecelerateInterpolator());animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {     @Override     public void onAnimationUpdate(ValueAnimator animation) {         float value = (float) animation.getAnimatedValue();         dst2.reset();         dst2.lineTo(0,0);         float start = value * pathMeasure2.getLength();         pathMeasure2.getSegment(start,pathMeasure2.getLength(),dst2,true);         postInvalidate();         }     });animator2 = ValueAnimator.ofFloat(0,1);animator2.setDuration(1000);animator2.setInterpolator(new AccelerateDecelerateInterpolator());animator2.setRepeatCount(ValueAnimator.INFINITE);animator2.setRepeatMode(ValueAnimator.RESTART);animator2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {     @Override     public void onAnimationUpdate(ValueAnimator animation) {          float value = (float) animation.getAnimatedValue();          dst.reset();          dst.lineTo(0,0);          float stop = value * pathMeasure.getLength();          float start = (float) (stop - (0.5 - Math.abs(value - 0.5)) * pathMeasure.getLength());          pathMeasure.getSegment(start,stop,dst,true);          postInvalidate();     }});animator.addListener(new Animator.AnimatorListener() {     @Override     public void onAnimationStart(Animator animation) {}     @Override     public void onAnimationEnd(Animator animation) {
 animator2.start();
         state = State.searching;     }     @Override     public void onAnimationCancel(Animator animation) {}     @Override     public void onAnimationRepeat(Animator animation) {}});

animator1是放大镜逐渐消失的动画,animator2是外面的圆圈不断的转的动画

可以看到,再animator中不断的取值,不断的构造新的path片段,连接起来就构成了动画

完整代码如下

public class MyView extends View{    private Path path1;    private Path path2;    private Path dst;    private Path dst2;    private PathMeasure pathMeasure;    private PathMeasure pathMeasure2;    private Paint paint;    private ValueAnimator animator;    private ValueAnimator animator2;    public static enum State {ready,start,searching};    private State state;    public MyView(Context context, AttributeSet attrs) {        super(context, attrs);        state = State.ready;        dst = new Path();        dst2 = new Path();        path1 = new Path();        path1.addArc(100,100,300,300,44,359.9f);        path2 = new Path();        path2.addArc(150,150,250,250,45,359.9f);        path2.lineTo((float) (200 + 85 * Math.sin(45)),(float) (200 + 85 * Math.sin(45)));        pathMeasure = new PathMeasure(path1,false);        pathMeasure2 = new PathMeasure(path2,false);        paint = new Paint();        paint.setStrokeWidth(15);        paint.setColor(Color.CYAN);        paint.setAntiAlias(true);        paint.setStrokeCap(Paint.Cap.ROUND);        paint.setStyle(Paint.Style.STROKE);        initAnim();    }    public void initAnim(){        animator = ValueAnimator.ofFloat(0,1);        animator.setDuration(800);        animator.setInterpolator(new AccelerateDecelerateInterpolator());        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                float value = (float) animation.getAnimatedValue();                dst2.reset();                dst2.lineTo(0,0);                float start = value * pathMeasure2.getLength();                pathMeasure2.getSegment(start,pathMeasure2.getLength(),dst2,true);                postInvalidate();            }        });        animator2 = ValueAnimator.ofFloat(0,1);        animator2.setDuration(1000);        animator2.setInterpolator(new AccelerateDecelerateInterpolator());        animator2.setRepeatCount(ValueAnimator.INFINITE);        animator2.setRepeatMode(ValueAnimator.RESTART);        animator2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                float value = (float) animation.getAnimatedValue();                dst.reset();                dst.lineTo(0,0);                float stop = value * pathMeasure.getLength();                float start = (float) (stop - (0.5 - Math.abs(value - 0.5)) * pathMeasure.getLength());                pathMeasure.getSegment(start,stop,dst,true);                postInvalidate();            }        });        animator.addListener(new Animator.AnimatorListener() {            @Override            public void onAnimationStart(Animator animation) {            }            @Override            public void onAnimationEnd(Animator animation) {                animator2.start();                state = State.searching;            }            @Override            public void onAnimationCancel(Animator animation) {            }            @Override            public void onAnimationRepeat(Animator animation) {            }        });    }    public void startAnim(){        state = State.start;        animator.start();    }    public void endAnim(){        if (animator != null) {            animator.end();        }        if (animator2 != null) {            animator2.end();        }        state = State.ready;        invalidate();    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        switch (state){            case ready:                canvas.drawPath(path2,paint);                break;            case start:                canvas.drawPath(dst,paint);                canvas.drawPath(dst2,paint);                break;            case searching:                canvas.drawPath(dst,paint);                break;        }    }}




0 0
原创粉丝点击