Android簡單炫酷SplashView

參考:
https://www.jianshu.com/p/6dd6c89220d9

https://blog.csdn.net/u010008118/article/details/103070847

https://blog.csdn.net/u014133119/article/details/80998025

效果展示

在這裏插入圖片描述

繪製六個圓

1 初始化

在colors.xml中添加6個顏色

    <color name="splash_bg">#F8F6EC</color>
    <color name="orange">#FF9600</color>
    <color name="aqua">#02D1AC</color>
    <color name="yellow">#FFD200</color>
    <color name="blue">#00C6FF</color>
    <color name="green">#00E099</color>
    <color name="pink">#FF3892</color>

    <array name="splash_circle_colors">
        <item>@color/blue</item>
        <item>@color/green</item>
        <item>@color/pink</item>
        <item>@color/orange</item>
        <item>@color/aqua</item>
        <item>@color/yellow</item>
    </array>

初始化顏色和畫筆

  	// 小圓圈的顏色列表,在initialize方法裏面初始化
    private int[] mCircleColors;
    // 繪製圓的畫筆
    private Paint mPaint = new Paint();

    public SplashView(Context context) {
        super(context);
        init(context);
    }
    private void init(Context context) {
        mCircleColors = context.getResources().getIntArray(R.array.splash_circle_colors);
        //消除鋸齒
        mPaint.setAntiAlias(true);
    }

確定屏幕中心點座標

    // 屏幕正中心點座標
    private float mCenterX;
    private float mCenterY;
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mCenterX = w / 2f;
        mCenterY = h / 2f;
    }

2 繪製六個小圓

mCircleColors這裏一共是6中顏色,分別對應6個小圓顏色
小圓間隔角度= 2π/小圓的個數
當前小圓的角度 = i * 間隔角度
當前小圓的 x座標 = 小圓半徑cos(a) + 小圓心X座標
當前小圓的 y座標 = 小圓半徑
sin(a) + 小圓心Y座標

    // 大圓(裏面包含很多小圓的)的半徑
    private float mRotationRadius = 90;
    // 每一個小圓的半徑
    private float mCircleRadius = 18;
    //當前大圓的半徑
    private float mCurrentRotationRadius = mRotationRadius;

 	@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawCircles(canvas);
    }

    private void drawCircles(Canvas canvas) {
        //每個小圓之間的間隔角度= 2π /  小圓的個數
        float rotetionAngle = (float) (2 * Math.PI / mCircleColors.length);
        for (int i = 0; i < mCircleColors.length; i++) {
            /**
             * x= r* cos(a) + centerX
             * y = r* sin(a) + centerY
             */
            double angle = i * rotetionAngle ;
            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 abstract class SplashState {
        public abstract void drawState(Canvas canvas);

        public void cancle() {

        }
    }

    /**
     * 旋轉動畫
     */
    private class RotateState extends SplashState {

        @Override
        public void drawState(Canvas canvas) {

        }
    }

    /**
     * 聚合動畫
     */
    private class MerginState extends SplashState {

        @Override
        public void drawState(Canvas canvas) {

        }
    }

    /**
     * 擴散動畫
     */
    private class ExpandState extends SplashState {

        @Override
        public void drawState(Canvas canvas) {

        }
    }
    //1、旋轉動畫
    private class RotateState extends SplashState {
        public RotateState() {
            //1、動畫的初始化工作,2、開啓動畫
            mAnimator = ValueAnimator.ofFloat(0f, (float) Math.PI * 2);
            mAnimator.setInterpolator(new LinearInterpolator());
            mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

                @Override
                public void onAnimationUpdate(ValueAnimator valueAnimator) {
                    mCurrentRotationAngle = (float) valueAnimator.getAnimatedValue();
                    postInvalidate();
                }
            });
            mAnimator.setDuration(mRotationDuration);
            //無限循環
            mAnimator.setRepeatCount(ValueAnimator.INFINITE);
            mAnimator.start();
        }

        @Override
        public void drawState(Canvas canvas) {
            //背景
            drawBackground(canvas);
            //繪製小圓
            drawCircles(canvas);
        }
    }
    //執行聚合動畫
    public void splashDisappear() {
        if (mState != null && mState instanceof RotateState) {
            RotateState rotateState = (RotateState) mState;
            rotateState.cencel();
            post(new Runnable() {
                @Override
                public void run() {
                    mState = new MergingState();
                }
            });
        }
    }
    //2、聚合動畫
    private class MergingState extends SplashState {
        public MergingState() {
            mAnimator = ValueAnimator.ofFloat(0f, mRotationRadius);
            mAnimator.setDuration(mRotationDuration);
            mAnimator.setInterpolator(new OvershootInterpolator(10f));// 向前甩一定值後再回到原來位置
            mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator valueAnimator) {
                    mCurrentRotationRadius = (float) valueAnimator.getAnimatedValue();
                    invalidate();
                }
            });
            mAnimator.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    super.onAnimationEnd(animation);
                    mState = new ExpandState();
                }
            });
            //反轉
            mAnimator.reverse();
        }

        @Override
        public void drawState(Canvas canvas) {
            //背景
            drawBackground(canvas);
            //繪製小圓
            drawCircles(canvas);
        }
    }
    //3、水波紋擴散動畫
    private class ExpandState extends SplashState {
        public ExpandState() {
            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);
        }
    }
public class MainActivity extends AppCompatActivity {

    private SplashView splashView;
    private FrameLayout mMainView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mMainView = new FrameLayout(this);
        ContentView contentView = new ContentView(this);
        mMainView.addView(contentView);
        splashView = new SplashView(this);
        mMainView.addView(splashView);
        setContentView(mMainView);
        startLoaddData();
    }

    private void startLoaddData() {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                //表示數據加載完畢,進入第二個狀態
                splashView.splashDisappear();
            }
        }, 3000);//延時時間
    }
}

Github:https://github.com/345166018/AndroidUI/tree/master/HxSplashView

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章