Android动画 - 仿58同城加载动画

Android动画 - 仿58同城加载动画

Android小彩虹2021-08-26 3:55:16250A+A-

效果图

分析动画

首先分析动画,如上图所示: 动画分为三部分,分别为上方跳动部分,中间阴影部分,和下方文字部分。

  • 上方跳动部分,三个几何图形,实现上抛下落(平移),上抛过程中几何图形进行旋转,到达最底部时,变换几何图形
  • 中间阴影部分,一个椭圆,进行缩放
  • 下方文字部分居中

进行绘制

主要运用Drawable动画进行绘制。

public class ShapeLoadingDrawable extends Drawable implements Animatable{
} 

先将上方部分三个几何图和中间部分椭圆形绘制出来

    //画圆
    private void drawCircle(Canvas canvas) {
        mPaint.setColor(Color.parseColor("#aa738ffe"));
        canvas.drawCircle(mWidth / 2, mHeight / 2, radius, mPaint);
    }
    //画正方形
    private void drawRect(Canvas canvas) {
        mPaint.setColor(Color.parseColor("#aae84e49"));
        canvas.drawRect(mWidth / 2 -rectLength/2, mHeight / 2 - rectLength/2, mWidth / 2 + rectLength/2, mHeight / 2 + rectLength/2, mPaint);
    }

    //画三角形
    private void drawTriangle(Canvas canvas) {
        mPaint.setColor(Color.parseColor("#aa72d572"));
        Path path = new Path();
        path.moveTo(mWidth / 2, mHeight / 2 - rectLength/2);
        path.lineTo((float) (mWidth / 2 - Math.sqrt(Math.pow(rectLength,2) / 3)), mHeight / 2 + rectLength/2);
        path.lineTo((float) (mWidth / 2 + Math.sqrt(Math.pow(rectLength,2) / 3)), mHeight / 2 + rectLength/2);
        path.close();
        canvas.drawPath(path, mPaint);
    }
    
    //画椭圆
    private void drawShadow(Canvas canvas) {
        mPaint.setColor(Color.parseColor("#25808080"));
        canvas.scale(scale, scale, mWidth / 2, mHeight / 2 + 90);
        canvas.drawArc(mWidth / 2 - rectLength/2, mHeight / 2 + 80, mWidth / 2 + 50, mHeight / 2 + 100, 0, 360, false, mPaint);
    }

进行动画部分代码编写,主要运用ValueAnimator

  • 分析动画:两个部分的动画,一个是上面几何图形的下落上抛动画,一个是中间阴影指示器放大缩小的动画,如果能这样组合就算实现了: 当几何图形下落时配合阴影放大,当几何图形上抛时配合中间阴影缩小。当几何图形下落到最低点时,变换几何图形
    /** * 上抛动画 */
    private void upAnimation() {
        final ValueAnimator upAnimation = ValueAnimator.ofFloat(0, -200);
        upAnimation.setInterpolator(new DecelerateInterpolator(1.2f));
        //为动画设置更新时候的监听
        upAnimation.addUpdateListener(new 
    ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                translateY = (float) upAnimation.getAnimatedValue();
                //刷新
                invalidateSelf();
            }
        });
        
        //监听动画结束,进行下落动画
        upAnimation.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                downAnimation();
            }
        });
        
        //缩放动画
        final ValueAnimator scaleAnimation = ValueAnimator.ofFloat(1, 0.3f);
        scaleAnimation.setInterpolator(new DecelerateInterpolator(1.2f));
        scaleAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                scale = (float) scaleAnimation.getAnimatedValue();
            }
        });

        //三角形旋转动画
        final ValueAnimator rotateTriangleAnimation = ValueAnimator.ofFloat(0, 120);
        rotateTriangleAnimation.setInterpolator(new DecelerateInterpolator(1.2f));
        rotateTriangleAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                rotateTriangle = (float) rotateTriangleAnimation.getAnimatedValue();
            }
        });
        //正方形旋转动画
        final ValueAnimator rotateRectAnimation = ValueAnimator.ofFloat(0, 180);
        rotateRectAnimation.setInterpolator(new DecelerateInterpolator(1.2f));
        rotateRectAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                rotateRect = (float) rotateRectAnimation.getAnimatedValue();
            }
        });


        upAnimatorSet = new AnimatorSet();
        upAnimatorSet.setDuration(300);
        upAnimatorSet.playTogether(upAnimation, scaleAnimation, rotateTriangleAnimation, rotateRectAnimation);
        upAnimatorSet.start();

    }

    
   /** * 下落动画 */
    private void downAnimation() {
        final ValueAnimator downAnimation = ValueAnimator.ofFloat(-200, 0);
        downAnimation.setInterpolator(new DecelerateInterpolator(1.2f));
        downAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                translateY = (float) downAnimation.getAnimatedValue();
                invalidateSelf();
            }
        });

        downAnimation.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                upAnimation();
                exchangeDraw();
            }
        });


        final ValueAnimator scaleAnimation = ValueAnimator.ofFloat(0.3f, 1);
        scaleAnimation.setInterpolator(new DecelerateInterpolator(1.2f));
        scaleAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                scale = (float) scaleAnimation.getAnimatedValue();
            }
        });
        downAnimatorSet = new AnimatorSet();
        downAnimatorSet.setDuration(500);
        downAnimatorSet.playTogether(downAnimation, scaleAnimation);
        downAnimatorSet.start();
    }

动画使用

在ImageView中设置drawable即可

ShapeLoadingDrawable shapeLoadingDrawable = new ShapeLoadingDrawable();
imageView.setImageDrawable(shapeLoadingDrawable);
shapeLoadingDrawable.start();

GitHub地址

有用记得点颗小星星

往期文章地址

Android动画 - 仿抖音加载动画

Android动画 - 仿花束直播加载动画

点击这里复制本文地址 以上内容由权冠洲的博客整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!

支持Ctrl+Enter提交

联系我们| 本站介绍| 留言建议 | 交换友链 | 域名展示
本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除

权冠洲的博客 © All Rights Reserved.  Copyright quanguanzhou.top All Rights Reserved
苏公网安备 32030302000848号   苏ICP备20033101号-1
本网站由 提供CDN/云存储服务

联系我们