旋转动画

来源:互联网 发布:湖北招生考试软件 编辑:程序博客网 时间:2024/05/10 12:05

旋转动画

使用的到策略模式

package com.splash.activity;import android.animation.Animator;import android.animation.ValueAnimator;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.support.annotation.Nullable;import android.util.AttributeSet;import android.view.View;import android.view.animation.LinearInterpolator;import android.view.animation.OvershootInterpolator;/** * 作者: songli * QQ : 2734030745 * 时间: 2017/6/16 2:28 * 邮箱: 15850774503@163.com. */public class SplashView extends View {    private ValueAnimator mAnimator;    //大圆的半径    private float mRotationRadius = 90;    //每个小圆的半径    private float mCircleRadius = 18;    //小圆的颜色列表, 在initialize方法里面初始化    private int[] mCircleColors;    //大圆和小圆旋转的时间    private long mRotationDuration = 1200; //ms    //第二部分动画的执行总时间    private long mSplashDuration = 1200; //ms    //整体的背景颜色    private int mSplashBgColor = Color.WHITE;    //空心圆初始半径    private float mHoleRadius = 0F;    //当前大圆旋转角度    private float mCurrentRotationAngle = 0F;    //当前大圆的半径    private float mCurrentRotationRadius = mRotationRadius;    //绘制圆的画笔    private Paint mPaint = new Paint();    //绘制背景的画笔    private Paint mPaitnBackground = new Paint();    //屏幕正中心点坐标    private float mCenterX;    private float mCenterY;    //屏幕对角线一半    private float mDiagonalDist;    public SplashView(Context context) {        super(context);        init(context);    }    public SplashView(Context context, @Nullable AttributeSet attrs) {        super(context, attrs);    }    private void init(Context context) {        mCircleColors = context.getResources().getIntArray(R.array.splash_circle_colors);        //画笔初始化        //消除锯齿        mPaint.setAntiAlias(true);        mPaitnBackground.setAntiAlias(true);        //设置样式----边框样式----描边        mPaitnBackground.setStyle(Paint.Style.STROKE);        mPaitnBackground.setColor(mSplashBgColor);    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        mCenterX = w / 2f;        mCenterY = h / 2f;        mDiagonalDist = (float) (Math.sqrt((w * w + h * h)) / 2f);    }    public void splashDisappear() {        //开启后面两个动画        //换模板---换状态        if (mState != null && mState instanceof RoateState)        {            //结束旋转动画            RoateState roateState = (RoateState) mState;            roateState.cancel();            post(new Runnable() {                @Override                public void run() {                    mState = new MergingState();                }            });        }    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        if (mState == null)        {            //开启第一个旋转动画            mState = new RoateState();        }        //调用 绘制方法        mState.drawState(canvas);    }    private SplashState mState = null;    ////策略模式:State---三种动画状态    private abstract class SplashState {        public abstract void drawState(Canvas canvas);    }    /**     * 1,旋转动画     * 控制各个小圆的坐标 --- 控制小圆的角度变化--属性动画ValueAnimator     */    private class RoateState extends SplashState {        public RoateState() {            //1,动画的初始工作, 2,开启动画            //花1200ms ,计算某个时刻当前的角度是多少? 0 - 2π            mAnimator = ValueAnimator.ofFloat(0f, (float) Math.PI * 2);            mAnimator.setInterpolator(new LinearInterpolator());            mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {                @Override                public void onAnimationUpdate(ValueAnimator animation) {                    //计算某个时刻当前的大圆旋转了的角度是多少?                    mCurrentRotationAngle = (float) animation.getAnimatedValue();                    invalidate();                }            });            mAnimator.setDuration(mRotationDuration);            mAnimator.setRepeatCount(ValueAnimator.INFINITE);            mAnimator.start();        }        public void cancel() {            mAnimator.cancel();        }        @Override        public void drawState(Canvas canvas) {            //1,背景----涂层白色            drawBackground(canvas);            //2,绘制小圆            drawCircles(canvas);        }    }    /**     * 2,     */    private class MergingState extends SplashState {        public MergingState() {            //花1200ms, 计算某个时刻当前的大圆半径是多少?  r ~ 0 中的某个值            mAnimator = ValueAnimator.ofFloat(0, mRotationRadius);            mAnimator.setDuration(mRotationDuration);            mAnimator.setInterpolator(new OvershootInterpolator(10f));            mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {                @Override                public void onAnimationUpdate(ValueAnimator animation) {                    //某个时刻当前大圆的半径是多少?                    mCurrentRotationRadius = (float) animation.getAnimatedValue();                    invalidate();                }            });            mAnimator.addListener(new Animator.AnimatorListener() {                @Override                public void onAnimationStart(Animator animation) {                }                @Override                public void onAnimationEnd(Animator animation) {                    mState = new ExpandState();                }                @Override                public void onAnimationCancel(Animator animation) {                }                @Override                public void onAnimationRepeat(Animator animation) {                }            });            mAnimator.reverse();        }        @Override        public void drawState(Canvas canvas) {//1,背景----涂层白色            drawBackground(canvas);            //2,绘制小圆            drawCircles(canvas);        }    }    /**     * 3,水波纹扩散动画     * 画一个空心圆----画一个圆,让它的画笔的粗细变成很大---不断地减小画笔的粗细。     * 空心圆变化的范围:0~ 对角线/2     */    private class  ExpandState extends SplashState    {        public ExpandState() {            //花1200ms,计算某个时刻当前的空心圆的半径是多少? r~0中的某个值            mAnimator = ValueAnimator.ofFloat(mCircleRadius, mDiagonalDist);            mAnimator.setDuration(mRotationDuration);            mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {                @Override                public void onAnimationUpdate(ValueAnimator valueAnimator) {                    //当前的空心圆的半径是多少?                    mHoleRadius = (float) valueAnimator.getAnimatedValue();                    invalidate();                }            });            mAnimator.start();        }        @Override        public void drawState(Canvas canvas) {            drawBackground(canvas);        }    }    private void drawCircles(Canvas canvas) {        //每个小圆的之间的间隔角度 = 2π/小圆的个数        float rotationAngle = (float) (2 * Math.PI / mCircleColors.length);        for (int i = 0; i < mCircleColors.length; i++) {            /**             * x = r * cos(a) + centerX             * y = r *  sin(a) + centerY             * 每个小圆i* 间隔 角度 + 旋转 的角度 = 当前小圆的真的角度             */            double angle = i * rotationAngle + mCurrentRotationAngle;            float cX = (float) (mCurrentRotationRadius * Math.cos(angle) + mCenterX);            float cY = (float) (mCurrentRotationRadius * Math.sin(angle) + mCenterY);            mPaint.setColor(mCircleColors[i]);            canvas.drawCircle(cX, cY, mCircleRadius, mPaint);        }    }    private void drawBackground(Canvas canvas) {        if (mHoleRadius > 0f) {            //得到画笔的宽度  = 对角线 / 2 - 空心圆的半径            float strokeWidth = mDiagonalDist - mHoleRadius;            mPaitnBackground.setStrokeWidth(strokeWidth);            //画圆的半径== 空心圆的半径 + 画笔的宽度  / 2            float radius = mHoleRadius + strokeWidth / 2;            canvas.drawCircle(mCenterX, mCenterY, radius, mPaint);        } else {            canvas.drawColor(mSplashBgColor);        }    }}
package com.splash.activity;import android.content.Context;import android.support.v7.widget.AppCompatImageView;/** * 作者: songli * QQ : 2734030745 * 时间: 2017/6/16 2:25 * 邮箱: 15850774503@163.com. */public class ContentView extends AppCompatImageView {    public ContentView(Context context) {        super(context);        setImageResource(R.mipmap.content);    }}
package com.splash.activity;import android.os.Handler;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.widget.FrameLayout;public class MainActivity extends AppCompatActivity {    private FrameLayout mMainView;    private SplashView splashView;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        //setContentView(R.layout.activity_main);        mMainView = new FrameLayout(this);        ContentView contentView = new ContentView(this);        mMainView.addView(contentView);        splashView = new SplashView(this);        mMainView.addView(splashView);        setContentView(mMainView);        //后台加载数据        startLoadData();    }    Handler handler = new Handler();    private void startLoadData() {        handler.postDelayed(new Runnable() {            @Override            public void run() {                //数据加载一半 进入主界面 --> 开启                splashView.splashDisappear();            }        }, 6000); //延迟时间    }}