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

作者: xzmmhello | 来源:发表于2020-10-14 14:48 被阅读0次

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

    效果图

    58LoadingView.gif

    分析动画

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

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

    进行绘制

    主要运用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();
    

    相关文章

      网友评论

        本文标题:Android动画 - 仿58同城加载动画

        本文链接:https://www.haomeiwen.com/subject/aqaipktx.html