自定义View时,用到Paint Canvas的一些温故,讲讲用路径绘画实现动画效果(基础篇 三)
转载请注明出处王亟亟的大牛之路
上礼拜上了一篇关于动画的自定义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;}@Overrideprotected 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;}@Overrideprotected 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() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {float value = (Float) animation.getAnimatedValue();// 获取当前点坐标封装到coordsmPathMeasure.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的一些温故,讲讲用路径绘画实现动画效果(基础篇 三)的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 微信免充值代金券、开通微信免充值立减与折
- 下一篇: 算法:最长公共子序列(输出所有最长公共子