• 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"/>
  • 相关阅读:
    变量的创建和初始化
    HDU 1114 Piggy-Bank (dp)
    HDU 1421 搬寝室 (dp)
    HDU 2059 龟兔赛跑 (dp)
    HDU 2571 命运 (dp)
    HDU 1574 RP问题 (dp)
    HDU 2577 How to Type (字符串处理)
    HDU 1422 重温世界杯 (dp)
    HDU 2191 珍惜现在,感恩生活 (dp)
    HH实习 acm算法部 1689
  • 原文地址:https://www.cnblogs.com/kangweifeng/p/4898016.html
Copyright © 2020-2023  润新知