QQ中的弹性球动画效果

来源:互联网 发布:删除内置软件 编辑:程序博客网 时间:2024/05/24 04:59
package com.test.myapplication;    import android.animation.Animator;  import android.animation.ObjectAnimator;  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.PointF;  import android.support.annotation.Nullable;  import android.util.AttributeSet;  import android.util.Log;  import android.view.MotionEvent;  import android.view.View;  import android.view.animation.AccelerateDecelerateInterpolator;    public class MyView extends View {        private float mHeight;      private float mWidth;      private float radius = 40f;      private float currentRadius;      private Paint mPaint;        private PointF mStickCenter;      private PointF mDragCenter;        public MyView(Context context) {          super(context);          init();      }        public MyView(Context context, @Nullable AttributeSet attrs) {          super(context, attrs);          init();      }          private void init() {          mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);          mPaint.setColor(Color.RED);          mPaint.setStyle(Paint.Style.FILL);      }        @Override      protected void onLayout(boolean changed, int left, int top, int right, int bottom) {          super.onLayout(changed, left, top, right, bottom);          mHeight = getHeight();          mWidth = getWidth();          currentRadius = radius;          mStickCenter = new PointF(mWidth / 2, mHeight / 2);          mDragCenter = new PointF(mWidth / 2, mHeight / 2);      }        @Override      protected void onDraw(Canvas canvas) {          super.onDraw(canvas);          float xdelta = mDragCenter.x - mStickCenter.x;          float ydelta = mDragCenter.y - mStickCenter.y;          float distance = (float) Math.sqrt(xdelta * xdelta + ydelta * ydelta);            //拖拽圆          canvas.drawCircle(mDragCenter.x, mDragCenter.y, radius, mPaint);            if (distance != 0) {              currentRadius = radius * (1 - Math.min(distance / 3, 100) / 100);              if (currentRadius < 5) {                  currentRadius = 5;              }                //变化圆              canvas.drawCircle(mStickCenter.x, mStickCenter.y, currentRadius, mPaint);                float cos = ydelta / distance;              float sin = xdelta / distance;              //变化圆切点1              PointF stick1 = new PointF();              stick1.x = mStickCenter.x - currentRadius * cos;              stick1.y = mStickCenter.y + currentRadius * sin;             //变化圆切点2              PointF stick2 = new PointF();              stick2.x = mStickCenter.x + currentRadius * cos;              stick2.y = mStickCenter.y - currentRadius * sin;              //拖拽圆切点2              PointF drag2 = new PointF();              drag2.x = mDragCenter.x + radius * cos;              drag2.y = mDragCenter.y - radius * sin;              //拖拽圆切点1              PointF drag1 = new PointF();              drag1.x = mDragCenter.x - radius * cos;              drag1.y = mDragCenter.y + radius * sin;              //控制点1              PointF control1 = new PointF();              control1.x = stick1.x + xdelta / 2;              control1.y = stick1.y + ydelta / 2;              //控制点2              PointF control2 = new PointF();              control2.x = stick2.x + xdelta / 2;              control2.y = stick2.y + ydelta / 2;                //贝塞尔曲线              Path path = new Path();              path.moveTo(stick1.x, stick1.y);              path.quadTo(control1.x, control1.y, drag1.x, drag1.y);              path.lineTo(drag2.x, drag2.y);              path.quadTo(control2.x, control2.y, stick2.x, stick2.y);              path.close();              canvas.drawPath(path, mPaint);          }      }        private float downX;      private float downY;        @Override      public boolean onTouchEvent(MotionEvent event) {          int action = event.getAction();          switch (action) {              case MotionEvent.ACTION_DOWN:                  downX = event.getX();                  downY = event.getY();                  break;              case MotionEvent.ACTION_MOVE:                  float x = event.getX();                  float y = event.getY();                  mDragCenter.x += x - downX;                  mDragCenter.y += y - downY;                  downX = x;                  downY = y;                  invalidate();                  break;              case MotionEvent.ACTION_UP:                  final float xoffset = mDragCenter.x - mWidth / 2;                  final float yoffset = mDragCenter.y - mHeight / 2;                  final float originalx = mDragCenter.x;                  final float originaly = mDragCenter.y;                  ValueAnimator va = ValueAnimator.ofFloat(0, 1);                  va.setInterpolator(new AccelerateDecelerateInterpolator());                  va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {                      @Override                      public void onAnimationUpdate(ValueAnimator animation) {                          float fraction = animation.getAnimatedFraction();                          mDragCenter.x = originalx - xoffset * fraction;                          mDragCenter.y = originaly - yoffset * fraction;                          invalidate();                      }                  });                  va.setDuration(300);                  va.start();                  break;          }            return true;      }  }  

原创粉丝点击