欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android 开发自定义加载进度框解析

程序员文章站 2022-03-23 09:35:36
思路: 自定义控件继承View 实现onLayout(),onDraw()方法获取控件的大小Canvas类绘制样式 传入参数改变进度框的样式状态 //实现三个方法默认调...
思路:

自定义控件继承View 实现onLayout(),onDraw()方法获取控件的大小Canvas类绘制样式 传入参数改变进度框的样式状态

//实现三个方法默认调用最多参数的一个
public SuperCircleView(Context context) {
    this(context, null);
}

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

public SuperCircleView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}

//配置传入的参数 初始化画笔
public SuperCircleView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SuperCircleView);
    mMinRadio = a.getInteger(R.styleable.SuperCircleView_min_circle_radio, 400);
    mRingWidth = a.getFloat(R.styleable.SuperCircleView_ring_width, 40);
    mSelect = a.getInteger(R.styleable.SuperCircleView_select, 7);
    mSelectAngle = a.getInteger(R.styleable.SuperCircleView_selec_angle, 3);

    mMinCircleColor = a.getColor(R.styleable.SuperCircleView_circle_color, Color.WHITE);
    mMaxCircleColor = a.getColor(R.styleable.SuperCircleView_max_circle_color, context.getResources().getColor(R.color.huise2));
    mRingNormalColor = a.getColor(R.styleable.SuperCircleView_ring_normal_color, context.getResources().getColor(R.color.huise));

    isShowSelect = a.getBoolean(R.styleable.SuperCircleView_is_show_select, false);
    mSelectRing = a.getInt(R.styleable.SuperCircleView_ring_color_select, 0);
    a.recycle();

    mMinRadio = ConvertDpAndPx.Dp2Px(context, mMinRadio);
    mRingWidth = ConvertDpAndPx.Dp2Px(context, mRingWidth);
    mSelect = ConvertDpAndPx.Dp2Px(context, mSelect);
    mSelectAngle = ConvertDpAndPx.Dp2Px(context, mSelectAngle);

    mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mPaint.setAntiAlias(true);

    this.setWillNotDraw(false);

    this.color[0] = Color.parseColor("#4D993B");
    this.color[2] = Color.parseColor("#4D993B");
    this.color[1] = Color.parseColor("#4D993B");
}
获取自定义控件的宽高、设置画笔
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    super.onLayout(changed, left, top, right, bottom);
    mViewWidth = getMeasuredWidth();
    mViewHeight = getMeasuredHeight();
    mViewCenterX = mViewWidth / 2;
    mViewCenterY = mViewHeight / 2;

    mRectF = new RectF(mViewCenterX - mMinRadio - mRingWidth / 2, mViewCenterY - mMinRadio - mRingWidth / 2,
            mViewCenterX + mMinRadio + mRingWidth / 2, mViewCenterY + mMinRadio + mRingWidth / 2);

    mRingAngleWidth = (360 - mSelect * mSelectAngle) / mSelect;

    mRectF1 = new RectF(mViewCenterX - mMinRadio, mViewCenterY - mMinRadio,
            mViewCenterX + mMinRadio, mViewCenterY + mMinRadio);

}
绘制图像
    @Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    /**
     * 显示彩色断大于总共的段数是错误的
     */
    if (isShowSelect && mSelectRing > mSelect) {
        return;
    }

    mPaint.setColor(mMinCircleColor);
    //        canvas.drawCircle(mViewCenterX, mViewCenterY, mMinRadio, mPaint);
    //画默认圆环
    drawNormalRing(canvas);
    //        //画灰色描边圆环
    //        drawNormalStrokeRing(canvas);
    //画彩色圆环
    drawColorRing(canvas);
}



    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.RectF;
    import android.graphics.SweepGradient;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.View;

    import com.growing.train.R;
    import com.growing.train.common.utils.ConvertDpAndPx;


    public class SuperCircleView extends View {

        private final String TAG = "SuperCircleView";

        private int mViewWidth; //view的宽
        private int mViewHeight;    //view的高
        private int mViewCenterX;   //view宽的中心点
        private int mViewCenterY;   //view高的中心点
        private int mMinRadio; //最里面白色圆的半径
        private float mRingWidth; //圆环的宽度
        private int mSelect;    //分成多少段
        private int mSelectAngle;   //每个圆环之间的间隔
        private int mMinCircleColor;    //最里面圆的颜色
        private int mMaxCircleColor;    //最外面圆的颜色
        private int mRingNormalColor;    //默认圆环的颜色
        private Paint mPaint;
        private int color[] = new int[3];   //渐变颜色
        private float mRingAngleWidth;  //每一段的角度
        private RectF mRectF; //圆环的矩形区域
        private RectF mRectF1; //圆环描边矩形区域
        private int mSelectRing = 100;        //要显示几段彩色
        private boolean isShowSelect = false;   //是否显示断

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

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

        public SuperCircleView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SuperCircleView);
            mMinRadio = a.getInteger(R.styleable.SuperCircleView_min_circle_radio, 400);
            mRingWidth = a.getFloat(R.styleable.SuperCircleView_ring_width, 40);
            mSelect = a.getInteger(R.styleable.SuperCircleView_select, 7);
            mSelectAngle = a.getInteger(R.styleable.SuperCircleView_selec_angle, 3);

            mMinCircleColor = a.getColor(R.styleable.SuperCircleView_circle_color, Color.WHITE);
            mMaxCircleColor = a.getColor(R.styleable.SuperCircleView_max_circle_color, context.getResources().getColor(R.color.huise2));
            mRingNormalColor = a.getColor(R.styleable.SuperCircleView_ring_normal_color, context.getResources().getColor(R.color.huise));

            isShowSelect = a.getBoolean(R.styleable.SuperCircleView_is_show_select, false);
            mSelectRing = a.getInt(R.styleable.SuperCircleView_ring_color_select, 0);
            a.recycle();

            mMinRadio = ConvertDpAndPx.Dp2Px(context, mMinRadio);
            mRingWidth = ConvertDpAndPx.Dp2Px(context, mRingWidth);
            mSelect = ConvertDpAndPx.Dp2Px(context, mSelect);
            mSelectAngle = ConvertDpAndPx.Dp2Px(context, mSelectAngle);

            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mPaint.setAntiAlias(true);

            this.setWillNotDraw(false);

            this.color[0] = Color.parseColor("#4D993B");
            this.color[2] = Color.parseColor("#4D993B");
            this.color[1] = Color.parseColor("#4D993B");
        }


        @Override
        protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
            super.onLayout(changed, left, top, right, bottom);
            mViewWidth = getMeasuredWidth();
            mViewHeight = getMeasuredHeight();
            mViewCenterX = mViewWidth / 2;
            mViewCenterY = mViewHeight / 2;

            mRectF = new RectF(mViewCenterX - mMinRadio - mRingWidth / 2, mViewCenterY - mMinRadio - mRingWidth / 2,
                    mViewCenterX + mMinRadio + mRingWidth / 2, mViewCenterY + mMinRadio + mRingWidth / 2);

            mRingAngleWidth = (360 - mSelect * mSelectAngle) / mSelect;

            mRectF1 = new RectF(mViewCenterX - mMinRadio, mViewCenterY - mMinRadio,
                    mViewCenterX + mMinRadio, mViewCenterY + mMinRadio);

        }

        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            /**
             * 显示彩色断大于总共的段数是错误的
             */
            if (isShowSelect && mSelectRing > mSelect) {
                return;
            }

            mPaint.setColor(mMinCircleColor);
    //        canvas.drawCircle(mViewCenterX, mViewCenterY, mMinRadio, mPaint);
            //画默认圆环
            drawNormalRing(canvas);
    //        //画灰色描边圆环
    //        drawNormalStrokeRing(canvas);
            //画彩色圆环
            drawColorRing(canvas);
        }

        /**
         * 画彩色圆环
         *
         * @param canvas
         */
        private void drawColorRing(Canvas canvas) {
            Paint ringColorPaint = new Paint(mPaint);
            ringColorPaint.setStyle(Paint.Style.STROKE);
            ringColorPaint.setStrokeWidth(mRingWidth);
            ringColorPaint.setAntiAlias(true);
            ringColorPaint.setStrokeJoin(Paint.Join.ROUND);
            ringColorPaint.setStrokeCap(Paint.Cap.ROUND);
            ringColorPaint.setShader(new SweepGradient(mViewCenterX, mViewCenterX, color, null));

            if (!isShowSelect) {
                canvas.drawArc(mRectF, 270, mSelectRing, false, ringColorPaint);
                return;
            }

            if (mSelect == mSelectRing && mSelectRing != 0 && mSelect != 0) {
                canvas.drawArc(mRectF, 270, 360, false, ringColorPaint);
            } else {
                Log.d(TAG, (mRingAngleWidth * mSelectRing + mSelectAngle + mSelectRing) + "");
                canvas.drawArc(mRectF, 270, mRingAngleWidth * mSelectRing + mSelectAngle * mSelectRing, false, ringColorPaint);
            }

            ringColorPaint.setShader(null);
            ringColorPaint.setColor(mMaxCircleColor);
            for (int i = 0; i < mSelectRing; i++) {
                canvas.drawArc(mRectF, 270 + (i * mRingAngleWidth + (i) * mSelectAngle), mSelectAngle, false, ringColorPaint);
            }
        }

        /**
         * 画默认圆环
         *
         * @param canvas
         */
        private void drawNormalRing(Canvas canvas) {
            Paint ringNormalPaint = new Paint(mPaint);
            ringNormalPaint.setStyle(Paint.Style.STROKE);
            ringNormalPaint.setStrokeWidth(mRingWidth);
            ringNormalPaint.setColor(mRingNormalColor);
            ringNormalPaint.setAntiAlias(true); //抗锯齿
            canvas.drawArc(mRectF, 270, 360, false, ringNormalPaint);
            if (!isShowSelect) {
                return;
            }
            ringNormalPaint.setColor(mMaxCircleColor);
            for (int i = 0; i < mSelect; i++) {
                canvas.drawArc(mRectF, 270 + (i * mRingAngleWidth + (i) * mSelectAngle), mSelectAngle, false, ringNormalPaint);
            }
        }

        /**
         * 画描边圆环
         *
         * @param canvas
         */
        private void drawNormalStrokeRing(Canvas canvas) {
            Paint ringNormalPaint = new Paint(mPaint);
            ringNormalPaint.setStyle(Paint.Style.STROKE);
            ringNormalPaint.setStrokeWidth(5);
            ringNormalPaint.setColor(mRingNormalColor);
            ringNormalPaint.setAntiAlias(true);
            canvas.drawArc(mRectF1, 270, 360, false, ringNormalPaint);
            if (!isShowSelect) {
                return;
            }
            ringNormalPaint.setColor(mMaxCircleColor);
            for (int i = 0; i < mSelect; i++) {
                canvas.drawArc(mRectF, 270 + (i * mRingAngleWidth + (i) * mSelectAngle), mSelectAngle, false, ringNormalPaint);
            }
        }

        /**
         * 显示几段
         *
         * @param i
         */
        public void setSelect(int i) {
            this.mSelectRing = i;
            this.invalidate();
        }

        /**
         * 断的总数
         *
         * @param i
         */
        public void setSelectCount(int i) {
            this.mSelect = i;
        }


        /**
         * 是否显示断
         *
         * @param b
         */
        public void setShowSelect(boolean b) {
            this.isShowSelect = b;
        }


        public void setColor(int[] color) {
            this.color = color;
        }
}

https://github.com/HayDar-Android/SuperCircleSample