自定义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的一些温故,讲讲用路径绘画实现动画效果(基础篇 三)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微信免充值代金券、开通微信免充值立减与折
- 下一篇: 算法:最长公共子序列(输出所有最长公共子