Android加载动画系列——GearsLoadingAnim

Android加载动画系列——GearsLoadingAnim

       Ios系统每次升级的时候,界面上的齿轮图标都会转动,今天就让我们来探索一下这个效果是怎么实现的吧~

让我们先来看看效果图:


1、GearsLoadingAnim.java源码如下:
public class GearsLoadingAnim extends View {

    private float mWidth = 0f;
    private Paint mPaint, mPaintWheelBig, mPaintWheelSmall, mPaintAxle, mPaintCenter;
    private float mPadding = 0f;
    private float mPaintCenterRadius;

    private float mWheelSmallLength, mWheelBigLength;

    private int mWheelSmallSpace = 8;
    private int mWheelBigSpace = 6;

    ValueAnimator valueAnimator = null;
    float mAnimatedValue = 0f;

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

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

    public GearsLoadingAnim(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();
        }
    }

    private void drawCircle(Canvas canvas) {
        canvas.drawCircle(mWidth / 2, mWidth / 2, mWidth / 2 - mPadding, mPaint);
        canvas.drawCircle(mWidth / 2, mWidth / 2, mWidth / 4, mPaint);
    }

    private void drawAxleAndCenter(Canvas canvas) {
        for (int i = 0; i < 3; i++) {
            float x2 = (float) ((mWidth / 2.f - mPadding) * Math.cos(i * (360 / 3) * Math.PI / 180f));
            float y2 = (float) ((mWidth / 2.f - mPadding) * Math.sin(i * (360 / 3) * Math.PI / 180f));
            float x = (float) (mPaintCenterRadius * Math.cos(i * (360 / 3) * Math.PI / 180f));
            float y = (float) (mPaintCenterRadius * Math.sin(i * (360 / 3) * Math.PI / 180f));
            canvas.drawLine(mWidth / 2 - x,
                    mWidth / 2 - y, mWidth / 2 - x2,
                    mWidth / 2 - y2, mPaintAxle);
        }
        canvas.drawCircle(mWidth / 2, mWidth / 2, mPaintCenterRadius, mPaintCenter);
    }

    private void drawWheelBig(Canvas canvas) {
        for (int i = 0; i < 360; i++) {
            int angle = (int) (mAnimatedValue * mWheelBigSpace + i);//顺时针
            float x = (float) ((mWidth / 2.f - mPadding + mWheelBigLength) * Math.cos(angle * Math.PI / 180f));
            float y = (float) ((mWidth / 2.f - mPadding + mWheelBigLength) * Math.sin(angle * Math.PI / 180f));
            float x2 = (float) ((mWidth / 2.f - mPadding) * Math.cos(angle * Math.PI / 180f));
            float y2 = (float) ((mWidth / 2.f - mPadding) * Math.sin(angle * Math.PI / 180f));
            canvas.drawLine(mWidth / 2.f - x, mWidth / 2.f - y, mWidth / 2.f - x2, mWidth / 2.f - y2, mPaintWheelBig);
        }
    }


    private void drawWheelSmall(Canvas canvas) {
        for (int i = 0; i < 360; i = i + mWheelSmallSpace) {
            int angle = (int) (360 - mAnimatedValue * mWheelBigSpace + i);
            float x = (float) ((mWidth / 4.f) * Math.cos(angle * Math.PI / 180f));
            float y = (float) ((mWidth / 4.f) * Math.sin(angle * Math.PI / 180f));
            float x2 = (float) ((mWidth / 4.f + mWheelSmallSpace) * Math.cos(angle * Math.PI / 180f));
            float y2 = (float) ((mWidth / 4.f + mWheelSmallSpace) * Math.sin(angle * Math.PI / 180f));
            canvas.drawLine(mWidth / 2.f - x, mWidth / 2.f - y,
                    mWidth / 2.f - x2, mWidth / 2.f - y2, mPaintWheelSmall);
        }
    }

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

        canvas.save();
        drawCircle(canvas);
        drawWheelBig(canvas);
        drawWheelSmall(canvas);
        drawAxleAndCenter(canvas);
        canvas.restore();
    }


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

    private void initPaint() {
        mPaintCenterRadius = dip2px(2.5f) / 2;
        mPaintCenter = new Paint();
        mPaintCenter.setAntiAlias(true);
        mPaintCenter.setStyle(Paint.Style.STROKE);
        mPaintCenter.setColor(Color.WHITE);
        mPaintCenter.setStrokeWidth(dip2px(0.5f));

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

        mPaintAxle = new Paint();
        mPaintAxle.setAntiAlias(true);
        mPaintAxle.setStyle(Paint.Style.STROKE);
        mPaintAxle.setColor(Color.WHITE);
        mPaintAxle.setStrokeWidth(dip2px(2f));

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

        mPaintWheelSmall = new Paint();
        mPaintWheelSmall.setAntiAlias(true);
        mPaintWheelSmall.setStyle(Paint.Style.STROKE);
        mPaintWheelSmall.setColor(Color.WHITE);
        mPaintWheelSmall.setStrokeWidth(dip2px(0.5f));

        mPadding = dip2px(5);
        mWheelSmallLength = dip2px(3);
        mWheelBigLength = dip2px(2.5f);
    }

    private ValueAnimator startViewAnim(int startF, final int endF, long time) {
        valueAnimator = ValueAnimator.ofInt(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 = (int) valueAnimator.getAnimatedValue();
                mAnimatedValue = mAnimatedValue / 100f;
                postInvalidate();
            }
        });

        valueAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
            }

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

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

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

    public void startAnim() {
        stopAnim();
        startViewAnim(1, 100, 300);
    }
}
 

 

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

 

<com.cyril.loadinganim.GearsLoadingAnim
    android:id="@+id/gearloading"
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:visibility="gone"
     />

 

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

 
gearsLoadingAnim = (GearsLoadingAnim) findViewById(R.id.gearloading);
gearsLoadingAnim.startAnim();
 

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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值