Android加載動畫__仿貪喫蛇

先看看效果吧,錄屏軟件錄出來的有點一卡一卡的,不曉得咋回事


源碼在這兒了,我也實在不曉得說啥子,畢竟第一次寫安靜

public class MyLoadingAnimView extends View {


    public MyLoadingAnimView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public MyLoadingAnimView(Context context) {
        super(context);
        init();
    }

    private RectF bigCircleRect;
    private double alphaLengh;
    private Paint bigCircle, smallCircle, eyeCircle;


    private void init() {
        initParams();
        bigCircle = new Paint();
        bigCircle.setColor(Color.RED);
        bigCircle.setAntiAlias(true);
        bigCircle.setStyle(Paint.Style.FILL);


        smallCircle = new Paint();
        smallCircle.setColor(Color.RED);
        smallCircle.setAntiAlias(true);
        smallCircle.setStyle(Paint.Style.FILL);

        eyeCircle = new Paint();
        eyeCircle.setColor(Color.WHITE);
        eyeCircle.setAntiAlias(true);
        eyeCircle.setStyle(Paint.Style.FILL);
    }


    /**
     * 大圓半徑等於當前科繪製的(bottm-top)/2
     */
    private int bigCircleRadious;
    private int bigCx;
    private int bigCy;

    private int smallCircleRadious;
    private int eyeCircleRadious;

    /**
     * 大圓半徑與小圓半徑的比例
     */

    private double BigWithSmallScale = 4.0;

    /**
     * 大圓半徑與大圓上的圓半徑的比例
     */

    private double BigWithEyeScale = 8.0;

    //初始化各種參數
    private void initParams() {
        //各種內邊距
        int paddIngLeft, paddingRight, paddingTop, paddingBottom;
        //當前可繪製view的所在位置
        int  left, top, bottom;

        paddIngLeft = getPaddingLeft();
        paddingRight = getPaddingRight();
        paddingTop = getPaddingTop();
        paddingBottom = getPaddingBottom();


        left = paddIngLeft;
        top = paddingTop;
        bottom = height - paddingBottom;

        bigCircleRadious = (int) ((bottom - top) / 2.0);

        bigCx = left + bigCircleRadious;
        bigCy = top + bigCircleRadious;


        smallCircleRadious = (int) (bigCircleRadious / BigWithSmallScale);
        //透明度的總長度:大圓半徑距離三份+大圓圓心距離,+smallmarign*2
        alphaLengh = bigCx + bigCircleRadious * 3 + smallMargin * 2;
        eyeCircleRadious = (int) (bigCircleRadious / BigWithEyeScale);

        //大圓所在矩形(左,上,右,下),這裏
        bigCircleRect = new RectF(left, top, left + bigCircleRadious * 2, bottom);
    }

    /**
     * 最大張開角度
     */
    private double maxLegth = 200;

    private void startAnim() {
        ObjectAnimator animator = ObjectAnimator.ofInt(this, "progress", (int) maxLegth, (int) 0);
        animator.setDuration(500);
        animator.setRepeatCount(-1);
        animator.setRepeatMode(ObjectAnimator.RESTART);
        animator.setInterpolator(new LinearInterpolator());
        animator.start();
    }

    private int currentAngle = 90;

    void setProgress(int angle) {
        currentAngle = angle;
        invalidate();
    }

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

        if (currentAngle >= maxLegth / 2.0) {
            //張開,
            double angle = maxLegth - currentAngle;
            startAngle = (int) (angle / 2);
            sweepAngle = (int) (360 - angle);
        } else {
            //閉合
            startAngle = currentAngle / 2;
            sweepAngle = 360 - currentAngle;
        }

        canvas.drawArc(bigCircleRect, startAngle, sweepAngle, true, bigCircle);

        //畫眼睛
        double line = (bigCircleRadious * 3) / 5.0;
        int eyeAngle = startAngle + 30;
        int eyeX = (int) (bigCx + (Math.cos(eyeAngle * Math.PI / 180) * line));
        int eyeY = (int) (bigCy - Math.sin(eyeAngle * Math.PI / 180) * line);
        canvas.drawCircle(eyeX, eyeY, eyeCircleRadious, eyeCircle);

        //畫第一個大圓
        //第一個圓到大圓的距離,
        int margin = (int) ((bigCircleRadious + smallMargin) * (currentAngle / maxLegth));
        int cx1 = bigCx + margin;

        smallCircle.setAlpha(getAlphaByCx(cx1));
        canvas.drawCircle(cx1, bigCy, smallCircleRadious, smallCircle);
        //畫第二個圓,第二個小圓最少要距離第一個圓一個bigCircleRadious的距離,這樣當大圓閉合的時候,纔不會進去
        int cx2 = cx1 + bigCircleRadious + smallMargin;
        smallCircle.setAlpha(getAlphaByCx(cx2));
        canvas.drawCircle(cx2, bigCy, smallCircleRadious, smallCircle);

        //畫第三個圓
        int cx3 = cx2 + bigCircleRadious;
        smallCircle.setAlpha(getAlphaByCx(cx3));
        canvas.drawCircle(cx3, bigCy, smallCircleRadious, smallCircle);
        if (!isStartAnim) {
            startAnim();
            isStartAnim = true;
        }
    }


    /**
     * 第一個小圓的距離和第二個小圓的距離
     */

    private int smallMargin = 10;

    private int getAlphaByCx(int cx1) {
        double v = (alphaLengh - cx1) / (alphaLengh);
        if (v < 0) {
            v = 0;
        } else if (v > 1) {
            v = 1;
        }
        return (int) (v * 255);
    }

    private boolean isStartAnim = false;
    private int widith = 100;
    private int height = 30;

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
        initParams();
    }


    private int measureHeight(int heightMeasureSpec) {
        int mode = MeasureSpec.getMode(heightMeasureSpec);
        int size = MeasureSpec.getSize(heightMeasureSpec);
        if (mode == MeasureSpec.EXACTLY) {
            height = size;
        } else {
            if (mode == MeasureSpec.AT_MOST) {
                height = Math.min(height, size);
            }
        }
        return height;
    }


    private int measureWidth(int widthMeasureSpec) {
        int mode = MeasureSpec.getMode(widthMeasureSpec);
        int size = MeasureSpec.getSize(widthMeasureSpec);
        if (mode == MeasureSpec.EXACTLY) {
            widith = size;
        } else {
            if (mode == MeasureSpec.AT_MOST) {
                widith = Math.min(widith, size);
            }
        }
        return widith;
    }


}


使用

 <MyLoadingAnimView
        android:layout_width="90dp"
        android:layout_height="40dp" />

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