Android加载动画系列—— GhostLoadingAnim

来源:互联网 发布:广西老年大学网络报名 编辑:程序博客网 时间:2024/06/06 05:35
Android加载动画系列——GhostLoadingAnim

有时候,我们玩一些冒险类的游戏,场景加载的时候会出现一个来回游荡的幽灵,今天就让我们来看看这个效果是怎么实现的吧~

让我们先来看看效果图:


1、GhostLoadingAnim.java源码如下:
public class GhostLoadingAnim extends View {    private Paint mPaint, mPaintHand, mPaintShadow, mPaintArms;    private float mWidth = 0f;    private float mHeight = 0f;    private RectF rectFGhost = new RectF();    private RectF rectFGhostShadow = new RectF();    private float mPadding = 0f;    int mskirtH = 0;    private Path path = new Path();    public GhostLoadingAnim(Context context) {        this(context, null);    }    public GhostLoadingAnim(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public GhostLoadingAnim(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        initPaint();    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        mWidth = getMeasuredWidth();        mHeight = getMeasuredHeight();        mPadding = 10;        mskirtH = (int) (mWidth / 40);    }    private void initPaint() {        mPaint = new Paint();        mPaint.setAntiAlias(true);        mPaint.setStyle(Paint.Style.FILL);        mPaint.setColor(Color.WHITE);        mPaintHand = new Paint();        mPaintHand.setAntiAlias(true);        mPaintHand.setStyle(Paint.Style.FILL);        mPaintHand.setColor(Color.argb(220, 0, 0, 0));        mPaintShadow = new Paint();        mPaintShadow.setAntiAlias(true);        mPaintShadow.setStyle(Paint.Style.FILL);        mPaintShadow.setColor(Color.argb(60, 0, 0, 0));        mPaintArms = new Paint();        mPaintArms.setAntiAlias(true);        mPaintArms.setStyle(Paint.Style.FILL);        mPaintArms.setStrokeWidth(8);        mPaintArms.setColor(Color.argb(150, 0, 0, 0));    }    private ValueAnimator valueAnimator;    private float mAnimatedValue = 0.f;    int onAnimationRepeatFlag = 1;    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        canvas.save();        float distance = (mWidth - 2 * mPadding) / 3 * 2 * mAnimatedValue;        rectFGhost.left = mPadding + distance;        rectFGhost.right = (mWidth - 2 * mPadding) / 3 + distance;        float moveY = 0f;        float moveYMax = mHeight / 4f / 2f;        float shadowHighMax = 5f;        float shadowHigh = 0f;        if (mAnimatedValue <= 0.25) {            moveY = (float) (moveYMax / 0.25 * mAnimatedValue);            rectFGhost.top = moveY;            rectFGhost.bottom = mHeight / 4 * 3 + moveY;            shadowHigh = shadowHighMax / 0.25f * mAnimatedValue;        } else if (mAnimatedValue > 0.25 && mAnimatedValue <= 0.5f) {            moveY = (float) (moveYMax / 0.25f * (mAnimatedValue - 0.25f));            rectFGhost.top = moveYMax - moveY;            rectFGhost.bottom = mHeight / 4 * 3 + moveYMax - moveY;            shadowHigh = shadowHighMax - shadowHighMax / 0.25f * (mAnimatedValue - 0.25f);        } else if (mAnimatedValue > 0.5 && mAnimatedValue <= 0.75f) {            moveY = (float) (moveYMax / 0.25 * (mAnimatedValue - 0.5f));            rectFGhost.top = moveY;            rectFGhost.bottom = mHeight / 4 * 3 + moveY;            shadowHigh = shadowHighMax / 0.25f * (mAnimatedValue - 0.5f);        } else if (mAnimatedValue > 0.75 && mAnimatedValue <= 1f) {            moveY = (float) (moveYMax / 0.25 * (mAnimatedValue - 0.75f));            rectFGhost.top = moveYMax - moveY;            rectFGhost.bottom = mHeight / 4 * 3 + moveYMax - moveY;            shadowHigh = shadowHighMax - shadowHighMax / 0.25f * (mAnimatedValue - 0.75f);        }        rectFGhostShadow.top = mHeight - 25 + shadowHigh;        rectFGhostShadow.bottom = mHeight - 5 - shadowHigh;        rectFGhostShadow.left = rectFGhost.left + 5 + shadowHigh * 3;        rectFGhostShadow.right = rectFGhost.right - 5 - shadowHigh * 3;        drawShadow(canvas);        drawHead(canvas);        drawBody(canvas);        drawHand(canvas);        canvas.restore();    }    private void drawShadow(Canvas canvas) {        canvas.drawArc(rectFGhostShadow, 0, 360, false, mPaintShadow);    }    private void drawHead(Canvas canvas) {        canvas.drawCircle(rectFGhost.left + rectFGhost.width() / 2,                rectFGhost.width() / 2 + rectFGhost.top,                rectFGhost.width() / 2 - 15,                mPaint);    }    private void drawHand(Canvas canvas) {        canvas.drawCircle(rectFGhost.left + rectFGhost.width() / 2 - mskirtH * 3 / 2 + mskirtH * onAnimationRepeatFlag,                rectFGhost.width() / 2 + mskirtH + rectFGhost.top,                mskirtH * 0.9f, mPaintHand);        canvas.drawCircle(rectFGhost.left + rectFGhost.width() / 2 + mskirtH * 3 / 2 + mskirtH * onAnimationRepeatFlag,                rectFGhost.width() / 2 + mskirtH + rectFGhost.top, mskirtH * 0.9f, mPaintHand);    }    float wspace = 10f;    float hspace = 10f;    private void drawBody(Canvas canvas) {        path.reset();        float x = (float) ((rectFGhost.width() / 2 - 15) * Math.cos(5 * Math.PI / 180f));        float y = (float) ((rectFGhost.width() / 2 - 15) * Math.sin(5 * Math.PI / 180f));        float x2 = (float) ((rectFGhost.width() / 2 - 15) * Math.cos(175 * Math.PI / 180f));        float y2 = (float) ((rectFGhost.width() / 2 - 15) * Math.sin(175 * Math.PI / 180f));        path.moveTo(rectFGhost.left + rectFGhost.width() / 2 - x, rectFGhost.width() / 2 - y + rectFGhost.top);        path.lineTo(rectFGhost.left + rectFGhost.width() / 2 - x2, rectFGhost.width() / 2 - y2 + rectFGhost.top);        path.quadTo(rectFGhost.right + wspace / 2, rectFGhost.bottom, rectFGhost.right - wspace, rectFGhost.bottom - hspace);        float a = mskirtH;        float m = (rectFGhost.width() - 2 * wspace) / 7f;        for (int i = 0; i < 7; i++) {            if (i % 2 == 0) {                path.quadTo(rectFGhost.right - wspace - m * i - (m / 2), rectFGhost.bottom - hspace - a, rectFGhost.right - wspace - (m * (i + 1)), rectFGhost.bottom - hspace);            } else {                path.quadTo(rectFGhost.right - wspace - m * i - (m / 2), rectFGhost.bottom - hspace + a, rectFGhost.right - wspace - (m * (i + 1)), rectFGhost.bottom - hspace);            }        }        path.quadTo(rectFGhost.left - 5, rectFGhost.bottom, rectFGhost.left + rectFGhost.width() / 2 - x, rectFGhost.width() / 2 - y + rectFGhost.top);        path.close();        canvas.drawPath(path, mPaint);    }    private ValueAnimator startViewAnim(float startF, float endF, long time) {        valueAnimator = ValueAnimator.ofFloat(startF, endF);        valueAnimator.setDuration(time);        valueAnimator.setInterpolator(new LinearInterpolator());        valueAnimator.setRepeatCount(ValueAnimator.INFINITE);        valueAnimator.setRepeatMode(ValueAnimator.RESTART);        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                mAnimatedValue = (float) valueAnimator.getAnimatedValue();                invalidate();            }        });        valueAnimator.addListener(new AnimatorListenerAdapter() {            @Override            public void onAnimationRepeat(Animator animation) {                super.onAnimationRepeat(animation);                onAnimationRepeatFlag = onAnimationRepeatFlag * -1;                if (onAnimationRepeatFlag == -1) {                    wspace = 22;                } else {                    wspace = -2;                }            }            @Override            public void onAnimationEnd(Animator animation) {                super.onAnimationEnd(animation);            }            @Override            public void onAnimationStart(Animator animation) {                super.onAnimationStart(animation);            }        });        if (!valueAnimator.isRunning()) {            wspace = -1;            valueAnimator.start();        }        return valueAnimator;    }    public void stopAnim() {        if (valueAnimator != null) {            clearAnimation();            valueAnimator.setRepeatCount(0);            valueAnimator.cancel();            valueAnimator.end();            mAnimatedValue = 0f;            wspace = 10;            onAnimationRepeatFlag = 1;            postInvalidate();        }    }    public void startAnim() {        stopAnim();        startViewAnim(0f, 1f, 2500);    }}
 

2、接着在layout布局文件中使用我们自定义的动画控件

 

<com.cyril.loadinganim.GhostLoadingAnim    android:id="@+id/ghostloadinganim"    android:layout_width="200dp"    android:layout_height="120dp"     />
  

3、然后在Activity中实现动画的播放和停止,使用事例如下:

 
ghostLoadingAnim = (GhostLoadingAnim) findViewById(R.id.ghostloadinganim);ghostLoadingAnim.startAnim();
 

4、  戳这里,小编带你去源码的下载地址:http://download.csdn.net/detail/zhimingshangyan/9582830

 

0 0
原创粉丝点击