Android加載動畫系列——FinePoiStarLoadingAnim

Android加載動畫系列——FinePoiStarLoadingAnim

我們在看一些美劇和日漫的時候,經常會有一些魔法師、信徒畫一些奇怪的法陣。尤其是在看到佐助的六芒星寫輪眼,我總是幻想自己能有一雙那樣的眼睛。今天就讓我們來畫一個六芒星法陣吧~

讓我們先來看看效果圖:


1、FinePoiStarLoadingAnim.java源碼如下:
public class FinePoiStarLoadingAnim extends View {

    private float mWidth = 0f;
    private float mPadding = 0f;
    private Paint mPaintLine, mPaintCircle;
    private int hornCount = 5;

    private List<Point> listPoint = new ArrayList<>();
    private boolean isDrawPath = true;
    RectF rectF = new RectF();

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

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

    public FinePoiStarLoadingAnim(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initPaint();
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (getMeasuredWidth() > getHeight())
            mWidth = getMeasuredHeight();
        else
            mWidth = getMeasuredWidth();
        mPadding = dip2px(1);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        setLayerType(LAYER_TYPE_SOFTWARE, null);
        listPoint.clear();
        for (int i = 0; i < hornCount; i++) {
            Point p = getPoint(mWidth / 2 - mPadding, (90 - 360 / hornCount) + 360 / hornCount * i);
            listPoint.add(p);
        }
        Point cp = null;

        float currenttime = (mAnimatedValue * 10 - (int) (mAnimatedValue * 10));

        if (mAnimatedValue >= 0 && mAnimatedValue <= 0.1f) {
            cp = drawOneEdge(currenttime, 1f, listPoint.get(0), listPoint.get(2));

            if (isDrawPath)
                drawPathEdge(canvas, listPoint.get(0), cp);
            else {

                canvas.drawCircle(mWidth / 2 - cp.x, mWidth / 2 - cp.y, mPadding, mPaintLine);
            }
        } else if (mAnimatedValue > 0.1f && mAnimatedValue <= 0.2f) {
            cp = drawOneEdge(currenttime, 1f, listPoint.get(2), listPoint.get(4));
            if (isDrawPath) {
                drawEdge(canvas, 1);
                drawPathEdge(canvas, listPoint.get(2), cp);
            } else
                canvas.drawCircle(mWidth / 2 - cp.x, mWidth / 2 - cp.y, mPadding, mPaintLine);


        } else if (mAnimatedValue > 0.2f && mAnimatedValue <= 0.3f) {
            cp = drawOneEdge(currenttime, 1f, listPoint.get(4), listPoint.get(1));
            if (isDrawPath) {
                drawEdge(canvas, 2);
                drawPathEdge(canvas, listPoint.get(4), cp);
            } else
                canvas.drawCircle(mWidth / 2 - cp.x, mWidth / 2 - cp.y, mPadding, mPaintLine);

        } else if (mAnimatedValue > 0.3f && mAnimatedValue <= 0.4f) {
            cp = drawOneEdge(currenttime, 1f, listPoint.get(1), listPoint.get(3));
            if (isDrawPath) {
                drawEdge(canvas, 3);
                drawPathEdge(canvas, listPoint.get(1), cp);
            } else
                canvas.drawCircle(mWidth / 2 - cp.x, mWidth / 2 - cp.y, mPadding, mPaintLine);

        } else if (mAnimatedValue > 0.4f && mAnimatedValue <= 0.5f) {
            cp = drawOneEdge(currenttime, 1f, listPoint.get(3), listPoint.get(0));
            if (isDrawPath) {
                drawEdge(canvas, 4);
                drawPathEdge(canvas, listPoint.get(3), cp);
            } else
                canvas.drawCircle(mWidth / 2 - cp.x, mWidth / 2 - cp.y, mPadding, mPaintLine);

        } else if (mAnimatedValue > 0.5f && mAnimatedValue <= 0.75f) {
            drawEdge(canvas, 5);
            rectF = new RectF(mPadding, mPadding,
                    mWidth - mPadding, mWidth - mPadding);
            canvas.drawArc(rectF, -180 + ((90 - 360 / hornCount)), 360 / 0.25f * (mAnimatedValue - 0.5f)
                    , false, mPaintCircle);
        } else {
            mPaintCircle.setStrokeWidth(dip2px(1.5f));
            mPaintLine.setShadowLayer(1, 1, 1, Color.WHITE);
            drawEdge(canvas, 5);
            rectF = new RectF(mPadding, mPadding,
                    mWidth - mPadding, mWidth - mPadding);
            canvas.drawArc(rectF, -180 + ((90 - 360 / hornCount)), 360
                    , false, mPaintCircle);


        }
        mPaintCircle.setStrokeWidth(dip2px(1.0f));
        mPaintLine.setShadowLayer(0, 1, 1, Color.WHITE);


    }


    private Point drawOneEdge(float currenttime, float alltime, Point startP, Point endP) {
        float x = startP.x - (startP.x - endP.x) / alltime * currenttime;
        float y = startP.y - (startP.y - endP.y) / alltime * currenttime;
        Point resPoint = new Point(x, y);
        return resPoint;
    }


    private void drawFirstEdge(Canvas canvas) {
        canvas.drawLine(mWidth / 2 - listPoint.get(0).x, mWidth / 2 - listPoint.get(0).y
                , mWidth / 2 - listPoint.get(2).x, mWidth / 2 - listPoint.get(2).y, mPaintLine);
    }

    private void drawSecondEdge(Canvas canvas) {
        canvas.drawLine(mWidth / 2 - listPoint.get(2).x, mWidth / 2 - listPoint.get(2).y
                , mWidth / 2 - listPoint.get(4).x, mWidth / 2 - listPoint.get(4).y, mPaintLine);
    }

    private void drawThirdEdge(Canvas canvas) {
        canvas.drawLine(mWidth / 2 - listPoint.get(4).x, mWidth / 2 - listPoint.get(4).y
                , mWidth / 2 - listPoint.get(1).x, mWidth / 2 - listPoint.get(1).y, mPaintLine);
    }

    private void drawFourthEdge(Canvas canvas) {
        canvas.drawLine(mWidth / 2 - listPoint.get(1).x, mWidth / 2 - listPoint.get(1).y
                , mWidth / 2 - listPoint.get(3).x, mWidth / 2 - listPoint.get(3).y, mPaintLine);
    }

    private void drawFifthEdge(Canvas canvas) {
        canvas.drawLine(mWidth / 2 - listPoint.get(3).x, mWidth / 2 - listPoint.get(3).y
                , mWidth / 2 - listPoint.get(0).x, mWidth / 2 - listPoint.get(0).y, mPaintLine);
    }

    private void drawPathEdge(Canvas canvas, Point start, Point end) {

        canvas.drawLine(mWidth / 2 - start.x, mWidth / 2 - start.y
                , mWidth / 2 - end.x, mWidth / 2 - end.y, mPaintLine);


    }


    private void drawEdge(Canvas canvas, int edgeCount) {
        switch (edgeCount) {
            case 1:
                drawFirstEdge(canvas);
                break;
            case 2:
                drawFirstEdge(canvas);
                drawSecondEdge(canvas);
                break;
            case 3:
                drawFirstEdge(canvas);
                drawSecondEdge(canvas);
                drawThirdEdge(canvas);


                break;
            case 4:
                drawFirstEdge(canvas);
                drawSecondEdge(canvas);
                drawThirdEdge(canvas);
                drawFourthEdge(canvas);

                break;
            case 5:
                drawFirstEdge(canvas);
                drawSecondEdge(canvas);
                drawThirdEdge(canvas);
                drawFourthEdge(canvas);
                drawFifthEdge(canvas);
                break;


        }


    }


    private void initPaint() {
        mPaintLine = new Paint();
        mPaintLine.setAntiAlias(true);
        mPaintLine.setStyle(Paint.Style.FILL);
        mPaintLine.setColor(Color.WHITE);
        mPaintLine.setStrokeWidth(dip2px(1f));


        mPaintCircle = new Paint();
        mPaintCircle.setAntiAlias(true);
        mPaintCircle.setStyle(Paint.Style.STROKE);
        mPaintCircle.setColor(Color.WHITE);
        mPaintCircle.setStrokeWidth(dip2px(1));

    }

    public int dip2px(float dpValue) {
        final float scale = getContext().getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    private Point getPoint(float radius, float angle) {
        float x = (float) ((radius) * Math.cos(angle * Math.PI / 180f));
        float y = (float) ((radius) * Math.sin(angle * Math.PI / 180f));

        Point p = new Point(x, y);
        return p;
    }


    private class Point {
        private float x;
        private float y;

        private Point(float x, float y) {
            this.x = x;
            this.y = y;
        }


    }

    public void startAnim() {
        stopAnim();
        startViewAnim(0f, 1f, 3500);
    }

    public void stopAnim() {
        if (valueAnimator != null) {
            clearAnimation();
            valueAnimator.setRepeatCount(0);
            valueAnimator.cancel();
            valueAnimator.end();
            mAnimatedValue = 0.75f;
            postInvalidate();
        }
    }


    ValueAnimator valueAnimator = null;
    float mAnimatedValue = 0.75f;

    private ValueAnimator startViewAnim(float startF, final 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 valueAnimator) {

                mAnimatedValue = (float) valueAnimator.getAnimatedValue();
                invalidate();
            }
        });
        valueAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);

            }

            @Override
            public void onAnimationStart(Animator animation) {
                super.onAnimationStart(animation);
            }

            @Override
            public void onAnimationRepeat(Animator animation) {
                super.onAnimationRepeat(animation);
            }
        });
        if (!valueAnimator.isRunning()) {
            valueAnimator.start();

        }

        return valueAnimator;
    }


    public void setDrawPath(boolean isDrawPath) {
        this.isDrawPath = isDrawPath;
    }


}

 

2、接着在layout佈局文件中使用我們自定義的動畫控件

 

<com.cyril.loadinganim.FinePoiStarLoadingAnim
    android:id="@+id/finepoistar"
    android:layout_width="80dp"
    android:layout_height="80dp"
    />

3、然後在Activity中實現動畫的播放和停止,使用事例如下:

 
finePoiStarLoadingAnim = (FinePoiStarLoadingAnim) findViewById(R.id.finepoistar);
finePoiStarLoadingAnim.startAnim();
 

4、  戳這裏,小編帶你去源碼的下載地址:http://download.csdn.net/detail/zhimingshangyan/9582830

 

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