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 GetSegmentViewContext context, AttributeSet attrs) { supercontext, attrs); setLayerTypeLAYER_TYPE_SOFTWARE, null); mPaint = new PaintPaint.ANTI_ALIAS_FLAG); mPaint.setStylePaint.Style.STROKE); mPaint.setStrokeWidth4); mPaint.setColorColor.BLACK); mDstPath = new Path); mCirclePath = new Path); mCirclePath.addCircle100, 100, 50, Path.Direction.CW); mPathMeasure = new PathMeasuremCirclePath, true); ValueAnimator animator = ValueAnimator.ofFloat0, 1); animator.setRepeatCountValueAnimator.INFINITE); animator.addUpdateListenernew ValueAnimator.AnimatorUpdateListener) { public void onAnimationUpdateValueAnimator animation) { mCurAnimValue = Float) animation.getAnimatedValue); invalidate); } }); animator.setDuration2000); animator.start); } @Override protected void onDrawCanvas canvas) { super.onDrawcanvas); float length = mPathMeasure.getLength); float stop = length * mCurAnimValue; float start = float) stop - 0.5 - Math.absmCurAnimValue - 0.5)) * length)); mDstPath.reset); canvas.drawColorColor.WHITE); mPathMeasure.getSegmentstart, stop, mDstPath, true);//用于截取整个path中某个片段,通过参数startD和stopD来控制截取的长度,并将截取后的path保存到参数dst中,最后一个参数表示起始点是否使用moveTo将路径的新起始点移到结果path的起始点中,通常设置为true // mPathMeasure.getSegment0, stop, mDstPath, true); canvas.drawPathmDstPath, 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 AliPayViewContext context, AttributeSet attrs) { supercontext, attrs); setLayerTypeLAYER_TYPE_SOFTWARE, null); mPaint = new PaintPaint.ANTI_ALIAS_FLAG); mPaint.setStylePaint.Style.STROKE); mPaint.setStrokeWidth4); mPaint.setColorColor.BLACK); mDstPath = new Path); mCirclePath = new Path); mCirclePath.addCirclemCentX, mCentY, mRadius, Path.Direction.CW); mCirclePath.moveTomCentX - mRadius / 2, mCentY); mCirclePath.lineTomCentX, mCentY + mRadius / 2); mCirclePath.lineTomCentX + mRadius / 2, mCentY - mRadius / 3); mPathMeasure = new PathMeasuremCirclePath, false); ValueAnimator animator = ValueAnimator.ofFloat0, 2); animator.addUpdateListenernew ValueAnimator.AnimatorUpdateListener) { public void onAnimationUpdateValueAnimator animation) { mCurAnimValue = Float) animation.getAnimatedValue); invalidate); } }); animator.setDuration4000); animator.start); } boolean mNext = false; @Override protected void onDrawCanvas canvas) { super.onDrawcanvas); canvas.drawColorColor.WHITE); if mCurAnimValue < 1) { float stop = mPathMeasure.getLength) * mCurAnimValue; mPathMeasure.getSegment0, stop, mDstPath, true); } else { if !mNext) { mNext = true; mPathMeasure.getSegment0, mPathMeasure.getLength), mDstPath, true); mPathMeasure.nextContour); //跳转到下一条曲线函数 } float stop = mPathMeasure.getLength) * mCurAnimValue - 1); mPathMeasure.getSegment0, stop, mDstPath, true); } canvas.drawPathmDstPath, 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 GetPosTanViewContext context, AttributeSet attrs) { supercontext, attrs); setLayerTypeLAYER_TYPE_SOFTWARE, null); mArrawBmp = BitmapFactory.decodeResourcegetResources), R.drawable.arraw); mPaint = new PaintPaint.ANTI_ALIAS_FLAG); mPaint.setStylePaint.Style.STROKE); mPaint.setStrokeWidth4); mPaint.setColorColor.BLACK); mDstPath = new Path); mCirclePath = new Path); mCirclePath.addCircle100, 100, 50, Path.Direction.CW); mPathMeasure = new PathMeasuremCirclePath, true);//true计算的path的闭合长度,false则测量当前path状态长度 ValueAnimator animator = ValueAnimator.ofFloat0, 1); animator.setRepeatCountValueAnimator.INFINITE);//无限循环 animator.addUpdateListenernew ValueAnimator.AnimatorUpdateListener) { public void onAnimationUpdateValueAnimator animation) { mCurAnimValue = Float) animation.getAnimatedValue); invalidate); } }); animator.setDuration2000); animator.start); } @Override protected void onDrawCanvas canvas) { super.onDrawcanvas); canvas.drawColorColor.WHITE); float length = mPathMeasure.getLength); //计算路径长度 float stop = length * mCurAnimValue; mDstPath.reset); mPathMeasure.getSegment0, stop, mDstPath, true); canvas.drawPathmDstPath, mPaint); /** * 箭头旋转、位移实现方式一: */ //计算方位角 // mPathMeasure.getPosTanstop, pos, tan);//用于得到路径上某一长度的位置,以及位置的证正切值 // float degrees = float) Math.atan2tan[1], tan[0]) * 180.0 / Math.PI); // Matrix matrix = new Matrix); // matrix.postRotatedegrees, mArrawBmp.getWidth) / 2, mArrawBmp.getHeight) / 2); // matrix.postTranslatepos[0] - mArrawBmp.getWidth) / 2, pos[1] - mArrawBmp.getHeight) / 2); /** * 箭头旋转、位移实现方式一: */ Matrix matrix = new Matrix); mPathMeasure.getMatrixstop, matrix, PathMeasure.POSITION_MATRIX_FLAG | PathMeasure.TANGENT_MATRIX_FLAG);//用于的到路径上某一长度的位置以及该位置的正切值的矩阵 matrix.preTranslate-mArrawBmp.getWidth) / 2, -mArrawBmp.getHeight) / 2); canvas.drawBitmapmArrawBmp, 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>
效果