package com.lcw.view; import android.animation.TypeEvaluator; 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.Point; import android.util.AttributeSet; import android.view.View; import android.view.animation.AccelerateDecelerateInterpolator; /** * 自定义View(二阶贝塞尔曲线滑动动画) * Create by: chenwei.li * Date: 2017/4/21 * Time: 下午11:47 * Email: [email protected] */ public class BezierMoveView extends View implements View.OnClickListener { //开始点和结束点 private int mStartXPoint; private int mStartYPoint; private int mEndXPoint; private int mEndYPoint; //控制点 private int mConXPoint; private int mConYPoint; //移动点 private int mMoveXPoint; private int mMoveYPoint; //路径和画笔 private Path mPath; private Paint mPaint; //圆形半径,画笔 private int mCircleRadius; private Paint mCirlcePaint; public BezierMoveView(Context context) { super(context); init(context); } public BezierMoveView(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public BezierMoveView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); } /** * 进行初始化的一些操作 */ private void init(Context context) { //设置各点的位置 mStartXPoint = 100; mStartYPoint = 100; mEndXPoint = 600; mEndYPoint = 600; mConXPoint = 400; mConYPoint = 0; mMoveXPoint = 100; mMoveYPoint = 100; //路径,画笔设置 mPath = new Path(); mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setColor(Color.BLUE); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(8); mCircleRadius = 20; mCirlcePaint = new Paint(Paint.ANTI_ALIAS_FLAG); mCirlcePaint.setColor(Color.BLUE); mCirlcePaint.setStyle(Paint.Style.FILL); setOnClickListener(this); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mPath.reset(); //贝塞尔曲线 mPath.moveTo(mStartXPoint, mStartYPoint); mPath.quadTo(mConXPoint, mConYPoint, mEndXPoint, mEndYPoint); canvas.drawPath(mPath, mPaint); //画圆 canvas.drawCircle(mStartXPoint, mStartYPoint, mCircleRadius, mCirlcePaint); canvas.drawCircle(mEndXPoint, mEndYPoint, mCircleRadius, mCirlcePaint); canvas.drawCircle(mEndXPoint, mEndYPoint, mCircleRadius, mCirlcePaint); } @Override public void onClick(View v) { ValueAnimator valueAnimator = ValueAnimator.ofObject(new CirclePointEvaluator(), new Point(mStartXPoint, mStartYPoint), new Point(mEndXPoint, mEndYPoint)); valueAnimator.setDuration(600); valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator()); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { Point point = (Point) animation.getAnimatedValue(); mMoveXPoint = point.x; mMoveYPoint = point.y; invalidate(); } }); valueAnimator.start(); } /** * 自定义Evaluator */ public class CirclePointEvaluator implements TypeEvaluator { /** * @param t 当前动画进度 * @param startValue 开始值 * @param endValue 结束值 * @return */ @Override public Object evaluate(float t, Object startValue, Object endValue) { Point startPoint = (Point) startValue; Point endPoint = (Point) endValue; float temp = 1 - t; int x = (int) (temp * temp * startPoint.x + 2 * t * temp * mConXPoint + t * t * endPoint.x); int y = (int) (temp * temp * startPoint.y + 2 * t * temp * mConYPoint + t * t * endPoint.y); return new Point(x,y); } } }