zoukankan      html  css  js  c++  java
  • android自定义控件之彩虹加载圆圈

    import android.animation.Animator;
    import android.animation.ObjectAnimator;
    import android.animation.ValueAnimator;
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Paint.Cap;
    import android.graphics.RectF;
    import android.util.AttributeSet;
    import android.util.Property;
    import android.view.View;
    import android.view.animation.AccelerateDecelerateInterpolator;
    import android.view.animation.Interpolator;
    import android.view.animation.LinearInterpolator;
    
    import com.xh.boke.R;
    
    /**
     * 彩虹加载圆圈
     * Created by Administrator on 2015/10/21 0021.
     */
    public class CircularProgress extends View {
    
        private static final Interpolator ANGLE_INTERPOLATOR = new LinearInterpolator();
        private static final Interpolator SWEEP_INTERPOLATOR = new AccelerateDecelerateInterpolator();
        private static final int ANGLE_ANIMATOR_DURATION = 2000;
        private static final int SWEEP_ANIMATOR_DURATION = 900;
        private static final int MIN_SWEEP_ANGLE = 30;
        private static final int DEFAULT_BORDER_WIDTH = 3;
        private final RectF fBounds = new RectF();
    
        private ObjectAnimator mObjectAnimatorSweep;
        private ObjectAnimator mObjectAnimatorAngle;
        private boolean mModeAppearing = true;
        private Paint mPaint;
        private float mCurrentGlobalAngleOffset;
        private float mCurrentGlobalAngle;
        private float mCurrentSweepAngle;
        private float mBorderWidth;
        private boolean mRunning;
        //彩虹的颜色
        private int[] mColors = {0xFFFF0000,0xFFFF7F00,0xFFFFFF00,0xFF00FF00,0xFF00FFFF,0xFF0000FF,0xFF8B00FF};
    
        private int mCurrentColorIndex;
        private int mNextColorIndex;
    
        public CircularProgress(Context context) {
            this(context, null);
        }
    
        public CircularProgress(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public CircularProgress(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
    
            float density = context.getResources().getDisplayMetrics().density;
            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircularProgress, defStyleAttr, 0);
            mBorderWidth = a.getDimension(R.styleable.CircularProgress_borderWidth,
                    DEFAULT_BORDER_WIDTH * density);
            a.recycle();
    
            mCurrentColorIndex = 0;
            mNextColorIndex = 1;
    
            mPaint = new Paint();
            mPaint.setAntiAlias(true);
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeCap(Cap.ROUND);
            mPaint.setStrokeWidth(mBorderWidth);
            mPaint.setColor(mColors[mCurrentColorIndex]);
    
            setupAnimations();
        }
    
        private void start() {
            if (isRunning()) {
                return;
            }
            mRunning = true;
            mObjectAnimatorAngle.start();
            mObjectAnimatorSweep.start();
            invalidate();
        }
    
        private void stop() {
            if (!isRunning()) {
                return;
            }
            mRunning = false;
            mObjectAnimatorAngle.cancel();
            mObjectAnimatorSweep.cancel();
            invalidate();
        }
    
        private boolean isRunning() {
            return mRunning;
        }
    
        @Override
        protected void onVisibilityChanged(View changedView, int visibility) {
            super.onVisibilityChanged(changedView, visibility);
            if (visibility == VISIBLE) {
                start();
            } else {
                stop();
            }
        }
    
        @Override
        protected void onAttachedToWindow() {
            start();
            super.onAttachedToWindow();
        }
    
        @Override
        protected void onDetachedFromWindow() {
            stop();
            super.onDetachedFromWindow();
        }
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            fBounds.left = mBorderWidth / 2f + .5f;
            fBounds.right = w - mBorderWidth / 2f - .5f;
            fBounds.top = mBorderWidth / 2f + .5f;
            fBounds.bottom = h - mBorderWidth / 2f - .5f;
        }
    
        @Override
        public void draw(Canvas canvas) {
            super.draw(canvas);
            float startAngle = mCurrentGlobalAngle - mCurrentGlobalAngleOffset;
            float sweepAngle = mCurrentSweepAngle;
            if (mModeAppearing) {
                mPaint.setColor(gradient(mColors[mCurrentColorIndex], mColors[mNextColorIndex],
                        mCurrentSweepAngle / (360 - MIN_SWEEP_ANGLE * 2)));
                sweepAngle += MIN_SWEEP_ANGLE;
            } else {
                startAngle = startAngle + sweepAngle;
                sweepAngle = 360 - sweepAngle - MIN_SWEEP_ANGLE;
            }
            canvas.drawArc(fBounds, startAngle, sweepAngle, false, mPaint);
        }
    
        private static int gradient(int color1, int color2, float p) {
            int r1 = (color1 & 0xff0000) >> 16;
            int g1 = (color1 & 0xff00) >> 8;
            int b1 = color1 & 0xff;
            int r2 = (color2 & 0xff0000) >> 16;
            int g2 = (color2 & 0xff00) >> 8;
            int b2 = color2 & 0xff;
            int newr = (int) (r2 * p + r1 * (1 - p));
            int newg = (int) (g2 * p + g1 * (1 - p));
            int newb = (int) (b2 * p + b1 * (1 - p));
            return Color.argb(255, newr, newg, newb);
        }
    
        private void toggleAppearingMode() {
            mModeAppearing = !mModeAppearing;
            if (mModeAppearing) {
                mCurrentColorIndex = ++mCurrentColorIndex % mColors.length;
                mNextColorIndex = ++mNextColorIndex % mColors.length;
                mCurrentGlobalAngleOffset = (mCurrentGlobalAngleOffset + MIN_SWEEP_ANGLE * 2) % 360;
            }
        }
        // ////////////////////////////////////////////////////////////////////////////
        // ////////////// Animation
    
        private Property<CircularProgress, Float> mAngleProperty = new Property<CircularProgress, Float>(Float.class, "angle") {
            @Override
            public Float get(CircularProgress object) {
                return object.getCurrentGlobalAngle();
            }
    
            @Override
            public void set(CircularProgress object, Float value) {
                object.setCurrentGlobalAngle(value);
            }
        };
    
        private Property<CircularProgress, Float> mSweepProperty = new Property<CircularProgress, Float>(Float.class, "arc") {
            @Override
            public Float get(CircularProgress object) {
                return object.getCurrentSweepAngle();
            }
    
            @Override
            public void set(CircularProgress object, Float value) {
                object.setCurrentSweepAngle(value);
            }
        };
    
        private void setupAnimations() {
            mObjectAnimatorAngle = ObjectAnimator.ofFloat(this, mAngleProperty, 360f);
            mObjectAnimatorAngle.setInterpolator(ANGLE_INTERPOLATOR);
            mObjectAnimatorAngle.setDuration(ANGLE_ANIMATOR_DURATION);
            mObjectAnimatorAngle.setRepeatMode(ValueAnimator.RESTART);
            mObjectAnimatorAngle.setRepeatCount(ValueAnimator.INFINITE);
    
            mObjectAnimatorSweep = ObjectAnimator.ofFloat(this, mSweepProperty, 360f - MIN_SWEEP_ANGLE * 2);
            mObjectAnimatorSweep.setInterpolator(SWEEP_INTERPOLATOR);
            mObjectAnimatorSweep.setDuration(SWEEP_ANIMATOR_DURATION);
            mObjectAnimatorSweep.setRepeatMode(ValueAnimator.RESTART);
            mObjectAnimatorSweep.setRepeatCount(ValueAnimator.INFINITE);
            mObjectAnimatorSweep.addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animation) {
    
                }
    
                @Override
                public void onAnimationEnd(Animator animation) {
    
                }
    
                @Override
                public void onAnimationCancel(Animator animation) {
    
                }
    
                @Override
                public void onAnimationRepeat(Animator animation) {
                    toggleAppearingMode();
                }
            });
        }
    
        public void setCurrentGlobalAngle(float currentGlobalAngle) {
            mCurrentGlobalAngle = currentGlobalAngle;
            invalidate();
        }
    
        public float getCurrentGlobalAngle() {
            return mCurrentGlobalAngle;
        }
    
        public void setCurrentSweepAngle(float currentSweepAngle) {
            mCurrentSweepAngle = currentSweepAngle;
            invalidate();
        }
    
        public float getCurrentSweepAngle() {
            return mCurrentSweepAngle;
        }
    }

    attrs.xml

    <resources>
        <!--progress -->
        <declare-styleable name="CircularProgress">
            <attr name="borderWidth" format="dimension" />
        </declare-styleable>
    </resources>

    应用(加命名空间xmlns:lmw="http://schemas.android.com/apk/res-auto")

    <!-- 最后一行是粗细 -->
    <xxx.CircularProgress
      android:layout_width="40dp"
      android:layout_height="40dp"
      lmw:borderWidth="4dp"/>
  • 相关阅读:
    win7一关机电脑就蓝屏
    win10系统怎么查自己电脑的IP地址[系统天地]
    Win7如何设置任务管理器的快捷键?[系统天地]
    Win10系统下安全登录密码忘记了怎么办【系统天地】
    Win7系统很卡应该如何解决?[系统天地]
    Win7系统运行慢如何解决?——系统天地
    Win7如何解决开机应用程序无法正常启动
    win10系统怎么切换独立显卡
    程序员的自我修养
    SQL学习笔记
  • 原文地址:https://www.cnblogs.com/kangweifeng/p/4898016.html
Copyright © 2011-2022 走看看