码迷,mamicode.com
首页 > 其他好文 > 详细

自定义View时,用到Paint Canvas的一些温故,讲讲用路径绘画实现动画效果(基础篇 三)

时间:2016-04-11 16:59:54      阅读:264      评论:0      收藏:0      [点我收藏+]

标签:

转载请注明出处王亟亟的大牛之路

上礼拜上了一篇关于动画的自定义View的文章,然后里面的实现是PathMeasure,然后这一部分貌似以前没有讲过,那么就再补一篇来介绍下这部分的知识(之前一篇的传送门:http://blog.csdn.net/ddwhan0123/article/details/51066859

直接说有点抽象,我们来看下演示的效果:

动的时候,是这样子

技术分享

那暂停是这样子

技术分享

其实这样的实现,一个个坐标增量画然后一直Invalidate也能做,但是写起来太麻烦,PathMeasure很好的解决了这部分问题。


理论

技术分享

PathMeasure的作用是什么?

测量路径的长度,也就是找到我们运行(或者说绘画)过程中的路径的点的集合。(再也不用找坐标啦!!)

我们要如何使用?

 PathMeasure pathMeasure=new PathMeasure();
 pathMeasure.setPath(path,true);

创建一个空对象,然后传入所需的路径和路径是否close掉了

当然也可以用另外一种构造函数,看你喜好了。

那么我们要如何获取途中的路径内容的操作?

执行 mPathMeasure.getPosTan(value, coords, null);获取我们想要获取的坐标信息,然后在动画的有效区间里展现出来,OK我们来看下源码

技术分享

包内容很简单,就一个自定义的View+寄存的Activity

package com.wjj.demo.view;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.animation.DecelerateInterpolator;

import com.wjj.demo.R;

public class CustomView extends View {

    ValueAnimator valueAnimator;

    private PathMeasure mPathMeasure;
    private Paint paint;
    private Path path;
    private float[] coords = new float[2];
    private int XDraw, YDraw;

    public CustomView(Context context) {
        super(context);
        init();
    }

    public CustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }


    private void init() {
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setStrokeWidth(10);
        path = new Path();
        path.moveTo(100, 100);
        path.lineTo(500, 100);
        path.lineTo(500, 500);
        path.lineTo(100, 500);
        path.lineTo(100, 100);

        mPathMeasure = new PathMeasure(path, true);

        coords = new float[2];
        coords[0] = 100;
        coords[1] = 100;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        XDraw = measureHandler(widthMeasureSpec);
        YDraw = measureHandler(heightMeasureSpec);
        setMeasuredDimension(XDraw, YDraw);
    }

    //尺寸测绘
    private int measureHandler(int measureSpec) {
        int vale = 520;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        if (specMode == MeasureSpec.EXACTLY) {
            vale = specSize;
        } else if (specMode == MeasureSpec.AT_MOST) {
            vale = Math.min(vale, specSize);
        } else {
            vale = 520;
        }
        return vale;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.WHITE);
        paint.setStyle(Paint.Style.STROKE);
        paint.setColor(getResources().getColor(R.color.plum));
        canvas.drawPath(path, paint);

        // 绘制对应目标
        paint.setColor(getResources().getColor(R.color.Violet));
        paint.setStyle(Paint.Style.FILL);
        canvas.drawCircle(coords[0], coords[1], 20, paint);

    }

    // 开启动画
    public void startAnim(long duration) {
        valueAnimator = ValueAnimator.ofFloat(0, mPathMeasure.getLength());
        Log.d("-->measure length", "measure length = " + mPathMeasure.getLength());
        valueAnimator.setDuration(duration);
        // 减速插值器
        valueAnimator.setInterpolator(new DecelerateInterpolator());
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (Float) animation.getAnimatedValue();
                // 获取当前点坐标封装到coords
                mPathMeasure.getPosTan(value, coords, null);
                postInvalidate();
            }
        });
        valueAnimator.start();

    }
    //停止动画
    public void stopAnim() {
        valueAnimator.cancel();
    }

}

重要的步骤已经有注解了,插值器等内容在以前的文章有写过,不清楚或者忘记的可以看这里:http://blog.csdn.net/ddwhan0123/article/details/50464283

然后解释下为什么在最初就给了容器数组一个坐标,因为不那么做,点开始的地方是在(0,0)

代码地址:https://github.com/ddwhan0123/BlogSample/tree/master/PathMeasureDemo

下载地址:https://github.com/ddwhan0123/BlogSample/blob/master/PathMeasureDemo/PathMeasureDemo.zip

自定义View时,用到Paint Canvas的一些温故,讲讲用路径绘画实现动画效果(基础篇 三)

标签:

原文地址:http://blog.csdn.net/ddwhan0123/article/details/51121860

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!