视差动画 - 雅虎新闻摘要加载

作者: 你也不知道 | 来源:发表于2020-06-15 20:57 被阅读0次

    1. 效果


    雅虎新闻摘要加载

    太多太多的评论我其实是不会回的,如果要说什么只能说抱歉。我承认很多视频链接没那么好找,但是你如果留意用心了,肯定能获取到以前所有的直播视频链接。

    2.分析和实现


    2.1 效果分析:

    写了那么多次效果,这个实现起来应该是个小 case ,留意观察有三部分动画
      1. 旋转动画,六个小球在不断地旋转
      2. 位移动画,六个小球往中心点聚合
      3. 扩散动画,当小球移动的最中心就开始扩散

    2.2 分步实现:

    1. 旋转动画,六个小球在不断地旋转

         /**
         * 绘制小圆的旋转动画
         */
        private class RotationState extends SplashState {
            private ValueAnimator mAnimator;
    
            public RotationState() {
                // 属性动画
                mAnimator = ValueAnimator.ofFloat(0, (float) Math.PI * 2);
                mAnimator.setDuration(ROTATION_ANIMATION_TIME);
                mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        // 不断获取值 当前大圆旋转的角度
                        mCurrentRotationAngle = (float) animation.getAnimatedValue();
                        // 提醒View重新绘制
                        invalidate();
                    }
                });
                mAnimator.setRepeatCount(-1);
                mAnimator.setInterpolator(new LinearInterpolator());
                // 开始计算
                mAnimator.start();
            }
    
            @Override
            public void draw(Canvas canvas) {
                canvas.drawColor(mSplashColor);
                // 绘制六个小圆 坐标
                float preAngle = (float) (2 * Math.PI / mCircleColors.length);
                for (int i = 0; i < mCircleColors.length; i++) {
                    mPaint.setColor(mCircleColors[i]);
                    // 初始角度 + 当前旋转的角度
                    double angle = i * preAngle + mCurrentRotationAngle;
                    float cx = (float) (mCenterX + mRotationRadius * Math.cos(angle));
                    float cy = (float) (mCenterY + mRotationRadius * Math.sin(angle));
                    canvas.drawCircle(cx, cy, mCircleRadius, mPaint);
                }
            }
    
            public void cancelAnimator() {
                mAnimator.cancel();
                mAnimator = null;
            }
        }
    

    2. 位移动画,六个小球往中心点靠拢

        /**
         * 绘制小圆的聚合动画
         */
        private class MergeState extends SplashState {
            private ValueAnimator mAnimator;
    
            public MergeState() {
                // 属性动画
                mAnimator = ValueAnimator.ofFloat(mRotationRadius, 0);
                mAnimator.setDuration(SPLASH_ANIMATION_TIME / 2);
                mAnimator.setInterpolator(new AnticipateInterpolator(6f));
                mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        // 不断获取值 当前大圆旋转的角度
                        mCurrentRotationRadius = (float) animation.getAnimatedValue();
                        // 提醒View重新绘制
                        invalidate();
                    }
                });
    
                mAnimator.addListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        mSplashState = new ExpandingState();
                    }
                });
    
                // 开始计算
                mAnimator.start();
            }
    
            @Override
            public void draw(Canvas canvas) {
                canvas.drawColor(mSplashColor);
                // 绘制六个小圆 坐标
                float preAngle = (float) (2 * Math.PI / mCircleColors.length);
                for (int i = 0; i < mCircleColors.length; i++) {
                    mPaint.setColor(mCircleColors[i]);
                    // 初始角度 + 当前旋转的角度
                    double angle = i * preAngle + mCurrentRotationAngle;
                    float cx = (float) (mCenterX + mCurrentRotationRadius * Math.cos(angle));
                    float cy = (float) (mCenterY + mCurrentRotationRadius * Math.sin(angle));
                    canvas.drawCircle(cx, cy, mCircleRadius, mPaint);
                }
            }
        }
    

    3. 扩散动画,当小球移动的最中心就开始扩散

        /**
         * 绘制小圆的扩散动画
         */
        private class ExpandingState extends SplashState {
            private ValueAnimator mAnimator;
    
            public ExpandingState() {
                // 属性动画
                mAnimator = ValueAnimator.ofFloat(0, mDiagonalDist);
                mAnimator.setDuration(SPLASH_ANIMATION_TIME/2);
                mAnimator.setInterpolator(new AccelerateInterpolator());
                mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        // 不断获取值 当前大圆旋转的角度
                        mHoleRadius = (float) animation.getAnimatedValue();
                        // 提醒View重新绘制
                        invalidate();
                    }
                });
                // 开始计算
                mAnimator.start();
            }
    
            @Override
            public void draw(Canvas canvas) {
                if (mHoleRadius > 0) {
                    float strokeWidth = mDiagonalDist - mHoleRadius;
                    mPaintBackground.setStrokeWidth(strokeWidth);
                    float radius = mHoleRadius + strokeWidth / 2;
                    canvas.drawCircle(mCenterX, mCenterY, radius, mPaintBackground);
                } else {
                    canvas.drawColor(mSplashColor);
                }
            }
        }
    

    这期是自定义 View 部分的最后一次写效果了,写得也比较简单,因为毕竟前面写过那么多次,关于画笔绘制和属性动画我就不再详讲了。

    所有分享大纲:Android进阶之旅 - 自定义View篇

    视频讲解地址:http://pan.baidu.com/s/1mhVUimO

    相关文章

      网友评论

        本文标题:视差动画 - 雅虎新闻摘要加载

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