Android動畫之旅(一)----小球彈起動畫

學習了一段時間安卓動畫 有時間會整理一下,先暫時這樣看吧.

小球彈起動畫

動畫組成:

1.主體是一個小球沿着運動軌跡做加速運動,然後設置循環,以及逆向播放.

2.在小球下落到最底部的時候,小球會產生形變.變成橢圓

3.在小球快要觸底的時候,會產生陰影.(陰影也是橢圓)

4.點擊變色主要是畫筆的繪製變色.
關鍵代碼:

package com.example.administrator.animationworkdemo.views;

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.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.animation.AccelerateInterpolator;

import java.util.Random;

/**
* Created by SuperD on 2017/2/15.
* 小球彈起的Loading加載動畫
*/

public class CircleLoadingView extends View implements View.OnClickListener {
//起始點
private int mStartPointX;
private int mStartPointY;
//結束點
private int mEndPointX;
private int mEndPointY;
//小球的運動點
private int mMovePointX;
private int mMovePointY;

//小球的半徑
private int mRadius = 20;
//運動軌跡的長度
private int mHeight;

//陰影區域的線
private Paint mPaint;
private Paint mHelperPaint;
private Path mHelpPath;

private int[] colors = {Color.BLACK, Color.BLUE, Color.DKGRAY, Color.GREEN, Color.RED, Color.YELLOW};


public CircleLoadingView(Context context) {
    this(context, null);
}

public CircleLoadingView(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

public CircleLoadingView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init();
}

private void init() {
    mHelpPath = new Path();
    //繪製輔助線和輔助點的畫筆
    mHelperPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mHelperPaint.setStyle(Paint.Style.FILL_AND_STROKE);
    mHelperPaint.setStrokeWidth(5);
    mHelperPaint.setColor(Color.BLUE);

    mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
    mPaint.setStrokeWidth(2);
    mPaint.setColor(Color.parseColor("#3F3B2D"));
    setOnClickListener(this);
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    //取起始點在屏幕中間
    mStartPointX = w / 2;
    mEndPointX = w / 2;
    mEndPointY = h / 2;
    mStartPointY = mEndPointY * 5 / 6;
    //設置小球的初始點
    mMovePointX = mStartPointX;
    mMovePointY = mStartPointY;
    //獲得運動軌跡的高度
    mHeight = mEndPointY - mStartPointY;
}

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

// //繪製小球的運動軌跡
// mHelpPath.reset();
// mHelpPath.moveTo(mStartPointX, mStartPointY);
// mHelpPath.lineTo(mEndPointX, mEndPointY);
// mHelpPath.close();
// canvas.drawPath(mHelpPath, mHelperPaint);

    //在下落到一定時刻存在橢圓效果
    int mDistance = mEndPointY - mMovePointY;
    if (mDistance >= mRadius) {
        canvas.drawCircle(mMovePointX, mMovePointY, mRadius, mHelperPaint);
    } else {
        //距離底端距離的碰撞比例
        float ratio = mDistance / mRadius;
        //將左右位置稍微拉伸一點,形成扁狀效果
        RectF oval = new RectF(
                mMovePointX - mRadius - 2,
                mMovePointY - mRadius - ratio * mRadius + 5,
                mMovePointX + mRadius + 2,
                mMovePointY + mRadius - ratio * mRadius);
        canvas.drawOval(oval, mHelperPaint);
    }

    //繪製底部陰影(注意陰影也是橢圓)
    float downRatio = (mMovePointY - mStartPointY) / (float) mHeight;
    //在行駛路徑後半段 出現陰影
    if (downRatio > 0.3) {
        RectF rectF = new RectF(
                mEndPointX - mRadius * downRatio,
                mEndPointY + 10,
                mEndPointX + mRadius * downRatio,
                mEndPointY + 15
        );
        canvas.drawOval(rectF, mPaint);
    }
}

@Override
public void onClick(View view) {
    //初始化動畫
    ValueAnimator mStartAnim = ValueAnimator.ofInt(mStartPointY, mEndPointY);
    mStartAnim.setInterpolator(new AccelerateInterpolator(1.2f));
    mStartAnim.setDuration(500);
    mStartAnim.setRepeatCount(ValueAnimator.INFINITE);
    mStartAnim.setRepeatMode(ValueAnimator.REVERSE);
    mStartAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator valueAnimator) {
            mMovePointY = (int) valueAnimator.getAnimatedValue();
            invalidate();
        }
    });
    mStartAnim.start();
}


/**
 * 設置圓球的顏色
 */
public void setCircleColor() {
    if (null != mHelperPaint && null != colors) {
        mHelperPaint.setColor(colors[new Random().nextInt(6)]);
    }
}

}

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