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" />

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值