Android

Android 高仿iOS加载动画

2020-07-29  本文已影响0人  窝窝_头

效果图

gggggg.gif

无需多言, 代码

/**
 * Project: android
 * ClassName: LoadingView
 * Date: 2020/7/28 15:34
 * Creator: voisen
 * Email: voisen@icloud.com
 * Version: 1.0
 * Description:  this is LoadingView description !
 */
public class LoadingView extends View {
    private String TAG = "LoadingView";

    //自定义变量区域
    private int num = 12;
    private float strokeWidth = 5;
    private int changeDelay = 75;
    private int color;
    private int minAlpha = 20;

    //以下变量为自计算, 无需修改
    private Paint mPaint;
    private PointF center = new PointF(0,0);
    private int alphaStep = 0;
    private float angleStep = 0f;
    private float baseAngle = 0f;
    private float maxRadius = 0.0f;
    private float minRadius = 0.0f;
    private Timer timer;

    private TimerTask timerTask = new TimerTask() {
        @Override
        public void run() {
            float a = baseAngle - angleStep;
            if (a % 360 == 0){
                a = 0;
            }
            baseAngle = a;
            postInvalidate();
        }
    };

    public LoadingView(@NonNull Context context) {
        this(context, null);
    }

    public LoadingView(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public LoadingView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.LoadingView);
        initAttrs(attributes);
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setDither(true);
        mPaint.setStrokeWidth(strokeWidth);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setColor(color);
        alphaStep = (0xff-minAlpha)/num;
        angleStep = -360.0f/num;
        timer = new Timer(false);
        timer.schedule(timerTask,0, changeDelay);
        setWillNotDraw(false);
    }

    private void initAttrs(TypedArray attributes) {
        minAlpha = attributes.getInt(R.styleable.LoadingView_minAlpha,0x11);
        changeDelay = attributes.getInt(R.styleable.LoadingView_runDuration,75);
        num = attributes.getInt(R.styleable.LoadingView_lineCount,12);
        strokeWidth = attributes.getDimension(R.styleable.LoadingView_lineWidth,5);
        color = attributes.getColor(R.styleable.LoadingView_lineColor,Color.parseColor("#555555"));
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
    }

    @Override
    protected void onDetachedFromWindow() {
        timerTask.cancel();
        timer.cancel();
        super.onDetachedFromWindow();
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        if (changed){
            center.x = getWidth()/2.0f;
            center.y = getHeight()/2.0f;
            maxRadius = Math.min(getWidth(),getHeight())/2 - strokeWidth - 5;
            minRadius = maxRadius/1.75f;
        }
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int desiredWidth = 80;
        int desiredHeight = 80;
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int width;
        int height;
        if (widthMode == MeasureSpec.EXACTLY) {
            width = widthSize;
        } else if (widthMode == MeasureSpec.AT_MOST) {
            width = Math.min(desiredWidth, widthSize);
        } else {
            width = desiredWidth;
        }
        if (heightMode == MeasureSpec.EXACTLY) {
            height = heightSize;
        } else if (heightMode == MeasureSpec.AT_MOST) {
            height = Math.min(desiredHeight, heightSize);
        } else {
            height = desiredHeight;
        }
        setMeasuredDimension(width, height);

        center.x = getWidth()/2.0f;
        center.y = getWidth()/2.0f;
        maxRadius = Math.min(getWidth(),getHeight())/2 - strokeWidth - 5;
        minRadius = maxRadius/1.75f;
    }

    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);
        double a;
        float x1,y1,x2,y2;
        for (int i = 0; i < num; i++) {
            a = angleStep * i + baseAngle;
            x1 = (float) (Math.cos(Math.PI*a/180.0) * minRadius);
            x2 = (float) (Math.cos(Math.PI*a/180.0) * maxRadius);

            y1 = (float) (Math.sin(Math.PI*a/180.0) * minRadius);
            y2 = (float) (Math.sin(Math.PI*a/180.0) * maxRadius);

            Path path = new Path();
            path.moveTo(center.x+x1,center.y+y1);
            path.lineTo(center.x+x2,center.y+y2);

            int alpha = 0xff - (i * alphaStep);
            mPaint.setAlpha(alpha);
            canvas.drawPath(path,mPaint);
        }
    }
}


<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="LoadingView">
        <attr name="minAlpha" format="integer"/>
        <attr name="runDuration" format="integer"/>
        <attr name="lineCount" format="integer"/>
        <attr name="lineWidth" format="dimension"/>
        <attr name="lineColor" format="color"/>
    </declare-styleable>
</resources>

作者言

喜欢请收藏点赞 ❤️

上一篇下一篇

猜你喜欢

热点阅读