利用pathMeasure實現路徑動畫
阿新 • • 發佈:2019-01-02
you ble eight bmp con nan @override int repeat
package com.loaderman.customviewdemo; import android.animation.ValueAnimator; import android.content.Context; import android.graphics.*; import android.util.AttributeSet; import android.view.View; public class GetSegmentView extends View { private Path mCirclePath, mDstPath;private Paint mPaint; private PathMeasure mPathMeasure; private Float mCurAnimValue; public GetSegmentView(Context context, AttributeSet attrs) { super(context, attrs); setLayerType(LAYER_TYPE_SOFTWARE, null); mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(4); mPaint.setColor(Color.BLACK); mDstPath = new Path(); mCirclePath = new Path(); mCirclePath.addCircle(100, 100, 50, Path.Direction.CW); mPathMeasure = new PathMeasure(mCirclePath, true); ValueAnimator animator = ValueAnimator.ofFloat(0, 1); animator.setRepeatCount(ValueAnimator.INFINITE); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { public void onAnimationUpdate(ValueAnimator animation) { mCurAnimValue = (Float) animation.getAnimatedValue(); invalidate(); } }); animator.setDuration(2000); animator.start(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); float length = mPathMeasure.getLength(); float stop = length * mCurAnimValue; float start = (float) (stop - ((0.5 - Math.abs(mCurAnimValue - 0.5)) * length)); mDstPath.reset(); canvas.drawColor(Color.WHITE); mPathMeasure.getSegment(start, stop, mDstPath, true); // mPathMeasure.getSegment(0, stop, mDstPath, true); canvas.drawPath(mDstPath, mPaint); } }
package com.loaderman.customviewdemo; 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.view.View; public class AliPayView extends View { private Path mCirclePath, mDstPath; private Paint mPaint; private PathMeasure mPathMeasure; private Float mCurAnimValue; private int mCentX = 100; private int mCentY = 100; private int mRadius = 50; public AliPayView(Context context, AttributeSet attrs) { super(context, attrs); setLayerType(LAYER_TYPE_SOFTWARE, null); mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(4); mPaint.setColor(Color.BLACK); mDstPath = new Path(); mCirclePath = new Path(); mCirclePath.addCircle(mCentX, mCentY, mRadius, Path.Direction.CW); mCirclePath.moveTo(mCentX - mRadius / 2, mCentY); mCirclePath.lineTo(mCentX, mCentY + mRadius / 2); mCirclePath.lineTo(mCentX + mRadius / 2, mCentY - mRadius / 3); mPathMeasure = new PathMeasure(mCirclePath, false); ValueAnimator animator = ValueAnimator.ofFloat(0, 2); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { public void onAnimationUpdate(ValueAnimator animation) { mCurAnimValue = (Float) animation.getAnimatedValue(); invalidate(); } }); animator.setDuration(4000); animator.start(); } boolean mNext = false; @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.WHITE); if (mCurAnimValue < 1) { float stop = mPathMeasure.getLength() * mCurAnimValue; mPathMeasure.getSegment(0, stop, mDstPath, true); } else { if (!mNext) { mNext = true; mPathMeasure.getSegment(0, mPathMeasure.getLength(), mDstPath, true); mPathMeasure.nextContour(); //跳轉到下一條曲線函數 } float stop = mPathMeasure.getLength() * (mCurAnimValue - 1); mPathMeasure.getSegment(0, stop, mDstPath, true); } canvas.drawPath(mDstPath, mPaint); } }
package com.loaderman.customviewdemo; import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PathMeasure; import android.util.AttributeSet; import android.view.View; public class GetPosTanView extends View { private Path mCirclePath, mDstPath; private Paint mPaint; private PathMeasure mPathMeasure; private Float mCurAnimValue; private Bitmap mArrawBmp; private float[] pos = new float[2]; private float[] tan = new float[2]; public GetPosTanView(Context context, AttributeSet attrs) { super(context, attrs); setLayerType(LAYER_TYPE_SOFTWARE, null); mArrawBmp = BitmapFactory.decodeResource(getResources(), R.drawable.arraw); mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(4); mPaint.setColor(Color.BLACK); mDstPath = new Path(); mCirclePath = new Path(); mCirclePath.addCircle(100, 100, 50, Path.Direction.CW); mPathMeasure = new PathMeasure(mCirclePath, true);//true計算的path的閉合長度,false則測量當前path狀態長度 ValueAnimator animator = ValueAnimator.ofFloat(0, 1); animator.setRepeatCount(ValueAnimator.INFINITE);//無限循環 animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { public void onAnimationUpdate(ValueAnimator animation) { mCurAnimValue = (Float) animation.getAnimatedValue(); invalidate(); } }); animator.setDuration(2000); animator.start(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.WHITE); float length = mPathMeasure.getLength(); //計算路徑長度 float stop = length * mCurAnimValue; mDstPath.reset(); mPathMeasure.getSegment(0, stop, mDstPath, true); canvas.drawPath(mDstPath, mPaint); /** * 箭頭旋轉、位移實現方式一: */ //計算方位角 // mPathMeasure.getPosTan(stop, pos, tan); // float degrees = (float) (Math.atan2(tan[1], tan[0]) * 180.0 / Math.PI); // Matrix matrix = new Matrix(); // matrix.postRotate(degrees, mArrawBmp.getWidth() / 2, mArrawBmp.getHeight() / 2); // matrix.postTranslate(pos[0] - mArrawBmp.getWidth() / 2, pos[1] - mArrawBmp.getHeight() / 2); /** * 箭頭旋轉、位移實現方式一: */ Matrix matrix = new Matrix(); mPathMeasure.getMatrix(stop, matrix, PathMeasure.POSITION_MATRIX_FLAG | PathMeasure.TANGENT_MATRIX_FLAG); matrix.preTranslate(-mArrawBmp.getWidth() / 2, -mArrawBmp.getHeight() / 2); canvas.drawBitmap(mArrawBmp, matrix, mPaint); } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <com.loaderman.customviewdemo.GetSegmentView android:layout_width="match_parent" android:layout_height="80dp"/> <com.loaderman.customviewdemo.AliPayView android:layout_width="match_parent" android:layout_height="80dp"/> <com.loaderman.customviewdemo.GetPosTanView android:layout_width="match_parent" android:layout_height="150dp"/> </LinearLayout>
效果
利用pathMeasure實現路徑動畫