Android实现跳动的小球加载动画效果

Android实现跳动的小球加载动画效果,第1张

概述先来看看效果图跳动小球做这个动画,需掌握:    1、属性动画

先来看看效果图

跳动的小球做这个动画,需掌握:

     1、属性动画

     2、Path类、Canvas类

     3、贝塞尔曲线

     4、SurfaceVIEw用法

     5、自定义attr属性

     6 、架构: 状态模式,控制器

     7 、自由落体,抛物线等概念

不多说了,直接上码

1.DancingVIEw.java

public class DancingVIEw extends SurfaceVIEw implements SurfaceHolder.Callback {  public static final int STATE_DOWN = 1;//向下状态  public static final int STATE_UP = 2;//向上状态  public static final int DEFAulT_POINT_RADIUS = 10;  public static final int DEFAulT_BALL_RADIUS = 13;  public static final int DEFAulT_liNE_WIDTH = 200;  public static final int DEFAulT_liNE_HEIGHT = 2;  public static final int DEFAulT_liNE_color = color.parsecolor("#FF9800");  public static final int DEFAulT_POINT_color = color.parsecolor("#9C27B0");  public static final int DEFAulT_BALL_color = color.parsecolor("#FF4081");  public static final int DEFAulT_DOWN_DURATION = 600;//ms  public static final int DEFAulT_UP_DURATION = 600;//ms  public static final int DEFAulT_FREEDOWN_DURATION = 1000;//ms  public static final int MAX_OFFSET_Y = 50;//水平下降最大偏移距离  public int PONIT_RADIUS = DEFAulT_POINT_RADIUS;//小球半径  public int BALL_RADIUS = DEFAulT_BALL_RADIUS;//小球半径  private Paint mPaint;  private Path mPath;  private int mlinecolor;  private int mPonitcolor;  private int mBallcolor;  private int mlinewidth;  private int mlineHeight;  private float mDowndistance;  private float mUpdistance;  private float freeBalldistance;  private ValueAnimator mDownController;//下落控制器  private ValueAnimator mUpController;//上d控制器  private ValueAnimator mFreeDownController;//自由落体控制器  private AnimatorSet animatorSet;  private int state;  private boolean ismUpControllerDIEd = false;  private boolean isAnimationShowing = false;  private boolean isBounced = false;  private boolean isBallFreeUp = false;  public DancingVIEw(Context context) {    super(context);    init(context,null);  }  public DancingVIEw(Context context,AttributeSet attrs) {    super(context,attrs);    init(context,attrs);  }  public DancingVIEw(Context context,AttributeSet attrs,int defStyleAttr) {    super(context,attrs,defStyleAttr);    init(context,attrs);  }  private voID init(Context context,AttributeSet attrs) {    initAttributes(context,attrs);    mPaint = new Paint();    mPaint.setAntiAlias(true);    mPaint.setstrokeWIDth(mlineHeight);    mPaint.setstrokeCap(Paint.Cap.ROUND);    mPath = new Path();    getHolder().addCallback(this);    initController();  }  private voID initAttributes(Context context,AttributeSet attrs) {    TypedArray typeArray = context.obtainStyledAttributes(attrs,R.styleable.DancingVIEw);    mlinecolor = typeArray.getcolor(R.styleable.DancingVIEw_linecolor,DEFAulT_liNE_color);    mlinewidth = typeArray.getDimensionPixelOffset(R.styleable.DancingVIEw_linewidth,DEFAulT_liNE_WIDTH);    mlineHeight = typeArray.getDimensionPixelOffset(R.styleable.DancingVIEw_lineHeight,DEFAulT_liNE_HEIGHT);    mPonitcolor = typeArray.getcolor(R.styleable.DancingVIEw_pointcolor,DEFAulT_POINT_color);    mBallcolor = typeArray.getcolor(R.styleable.DancingVIEw_ballcolor,DEFAulT_BALL_color);    typeArray.recycle();  }  private voID initController() {    mDownController = ValueAnimator.offloat(0,1);    mDownController.setDuration(DEFAulT_DOWN_DURATION);    mDownController.setInterpolator(new DecelerateInterpolator());    mDownController.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {      @OverrIDe      public voID onAnimationUpdate(ValueAnimator animation) {        mDowndistance = MAX_OFFSET_Y * (float) animation.getAnimatedValue();        postInvalIDate();      }    });    mDownController.addListener(new Animator.AnimatorListener() {      @OverrIDe      public voID onAnimationStart(Animator animation) {        state = STATE_DOWN;      }      @OverrIDe      public voID onAnimationEnd(Animator animation) {      }      @OverrIDe      public voID onAnimationCancel(Animator animation) {      }      @OverrIDe      public voID onAnimationRepeat(Animator animation) {      }    });    mUpController = ValueAnimator.offloat(0,1);    mUpController.setDuration(DEFAulT_UP_DURATION);    mUpController.setInterpolator(new DancingInterpolator());    mUpController.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {      @OverrIDe      public voID onAnimationUpdate(ValueAnimator animation) {        mUpdistance = MAX_OFFSET_Y * (float) animation.getAnimatedValue();        if (mUpdistance >= MAX_OFFSET_Y) {          //进入自由落体状态          isBounced = true;          if (!mFreeDownController.isRunning() && !mFreeDownController.isstarted() && !isBallFreeUp) {            mFreeDownController.start();          }        }        postInvalIDate();      }    });    mUpController.addListener(new Animator.AnimatorListener() {      @OverrIDe      public voID onAnimationStart(Animator animation) {        state = STATE_UP;      }      @OverrIDe      public voID onAnimationEnd(Animator animation) {        ismUpControllerDIEd = true;      }      @OverrIDe      public voID onAnimationCancel(Animator animation) {      }      @OverrIDe      public voID onAnimationRepeat(Animator animation) {      }    });    mFreeDownController = ValueAnimator.offloat(0,8f);    mFreeDownController.setDuration(DEFAulT_FREEDOWN_DURATION);    mFreeDownController.setInterpolator(new DecelerateInterpolator());    mFreeDownController.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {      @OverrIDe      public voID onAnimationUpdate(ValueAnimator animation) {        //该公式解决上升减速 和 下降加速        float t = (float) animation.getAnimatedValue();        freeBalldistance = 40 * t - 5 * t * t;        if (ismUpControllerDIEd) {//往上抛,到临界点          postInvalIDate();        }      }    });    mFreeDownController.addListener(new Animator.AnimatorListener() {      @OverrIDe      public voID onAnimationStart(Animator animation) {        isBallFreeUp = true;      }      @OverrIDe      public voID onAnimationEnd(Animator animation) {        isAnimationShowing = false;        //循环第二次        startAnimations();      }      @OverrIDe      public voID onAnimationCancel(Animator animation) {      }      @OverrIDe      public voID onAnimationRepeat(Animator animation) {      }    });    animatorSet = new AnimatorSet();    animatorSet.play(mDownController).before(mUpController);    animatorSet.addListener(new Animator.AnimatorListener() {      @OverrIDe      public voID onAnimationStart(Animator animation) {        isAnimationShowing = true;      }      @OverrIDe      public voID onAnimationEnd(Animator animation) {      }      @OverrIDe      public voID onAnimationCancel(Animator animation) {      }      @OverrIDe      public voID onAnimationRepeat(Animator animation) {      }    });  }  /**   * 启动动画,外部调用   */  public voID startAnimations() {    if (isAnimationShowing) {      return;    }    if (animatorSet.isRunning()) {      animatorSet.end();      animatorSet.cancel();    }    isBounced = false;    isBallFreeUp = false;    ismUpControllerDIEd = false;    animatorSet.start();  }  @OverrIDe  protected voID onDraw(Canvas canvas) {    super.onDraw(canvas);    // 一条绳子用左右两部分的二阶贝塞尔曲线组成    mPaint.setcolor(mlinecolor);    mPath.reset();    //起始点    mPath.moveto(getWIDth() / 2 - mlinewidth / 2,getHeight() / 2);    if (state == STATE_DOWN) {//下落      /**************绘制绳子开始*************/      //左部分 的贝塞尔      mPath.quadTo((float) (getWIDth() / 2 - mlinewidth / 2 + mlinewidth * 0.375),getHeight() / 2 + mDowndistance,getWIDth() / 2,getHeight() / 2 + mDowndistance);      //右部分 的贝塞尔      mPath.quadTo((float) (getWIDth() / 2 + mlinewidth / 2 - mlinewidth * 0.375),getWIDth() / 2 + mlinewidth / 2,getHeight() / 2);      mPaint.setStyle(Paint.Style.stroke);      canvas.drawPath(mPath,mPaint);      /**************绘制绳子结束*************/      /**************绘制d跳小球开始*************/      mPaint.setStyle(Paint.Style.FILL);      mPaint.setcolor(mBallcolor);      canvas.drawCircle(getWIDth() / 2,getHeight() / 2 + mDowndistance - BALL_RADIUS,BALL_RADIUS,mPaint);      /**************绘制d跳小球结束*************/    } else if (state == STATE_UP) { //向上d      /**************绘制绳子开始*************/      //左部分的贝塞尔      mPath.quadTo((float) (getWIDth() / 2 - mlinewidth / 2 + mlinewidth * 0.375),getHeight() / 2 + 50 - mUpdistance,getHeight() / 2 + (50 - mUpdistance));      //右部分的贝塞尔      mPath.quadTo((float) (getWIDth() / 2 + mlinewidth / 2 - mlinewidth * 0.375),mPaint);      /**************绘制绳子结束*************/      mPaint.setStyle(Paint.Style.FILL);      mPaint.setcolor(mBallcolor);      //d性小球,自由落体      if (!isBounced) {        //上升        canvas.drawCircle(getWIDth() / 2,getHeight() / 2 + (MAX_OFFSET_Y - mUpdistance) - BALL_RADIUS,mPaint);      } else {        //自由落体        canvas.drawCircle(getWIDth() / 2,getHeight() / 2 - freeBalldistance - BALL_RADIUS,mPaint);      }    }    mPaint.setcolor(mPonitcolor);    mPaint.setStyle(Paint.Style.FILL);    canvas.drawCircle(getWIDth() / 2 - mlinewidth / 2,getHeight() / 2,PONIT_RADIUS,mPaint);    canvas.drawCircle(getWIDth() / 2 + mlinewidth / 2,mPaint);  }  @OverrIDe  public voID surfaceCreated(SurfaceHolder holder) {    Canvas canvas = holder.lockCanvas();//锁定整个SurfaceVIEw对象,获取该Surface上的Canvas.    draw(canvas);    holder.unlockCanvasAndPost(canvas);//释放画布,提交修改  }  @OverrIDe  public voID surfaceChanged(SurfaceHolder holder,int format,int wIDth,int height) {  }  @OverrIDe  public voID surfaceDestroyed(SurfaceHolder holder) {  }}

2.DancingInterpolator.java

 public class DancingInterpolator implements Interpolator {  @OverrIDe  public float getInterpolation(float input) {    return (float) (1 - Math.exp(-3 * input) * Math.cos(10 * input));  }}

3.自定义属性 styles.xml

<declare-styleable name="DancingVIEw">    <attr name="linewidth" format="dimension" />    <attr name="lineHeight" format="dimension" />    <attr name="pointcolor" format="reference|color" />    <attr name="linecolor" format="reference|color" />    <attr name="ballcolor" format="reference|color" /></declare-styleable>

注意:颜色、尺寸、参数可以自己测试,调整。

以上就是本文的全部内容,希望对大家的学习和工作能有所帮助哦。

总结

以上是内存溢出为你收集整理的Android实现跳动的小球加载动画效果全部内容,希望文章能够帮你解决Android实现跳动的小球加载动画效果所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1148537.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存