Android一个带刻度的渐变半圆流量加载自定义View

 一.效果图(文字是自己UI绘制的,此自定义VIew是双圆)

二.在styles在配置declare-styleable

    <declare-styleable name="CircleProgressView">
        //背景颜色
        <attr name="outerColor" format="color"/>
        //圆弧颜色
        <attr name="innerColor" format="color"/>
        //弧宽度
        <attr name="borderWidth" format="dimension"/>
        //渐变色起始颜色
        <attr name="foreStartColor" format="color" />
        //渐变色结束颜色
        <attr name="foreEndColor" format="color" />
    </declare-styleable>

三.绘制自定义VIew

public class CircleProgressView extends View {

    private static final String TAG = CircleProgressView.class.getSimpleName();
    //#EFEFEF
//#47C496
    private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    LinearGradient gradient;
    //画笔宽度,线段长度,最后一条大线条的长度 比其他线段长的长度
    private int strokeWidth = 3, lineLength =40, maxLineLength = 0;
    //绘制文本距离圆
    private int txtMargin = 10;
    //中心点坐标
    private int centerX, centerY;
    //内圆半径,外圆半径
    private int innerRadius, outRadius;

    //绘制文本
    private String leftText = "", rightText = "";

    //绘制文本的字体大小
    private int textSize = 25;

    //背景 or 进度条颜色
    private int colorBackground = Color.parseColor("#0FD4DEFA");
    private int colorProgress = Color.parseColor("#18C8C7");
    private int colorText = Color.parseColor("#999999");
    float fullAngle = 180f;
    float cutAngle = 90f;

    //每个线段相隔的宽度
    private static final int perAngle = 6;
    private int startAngle = 0;
    private RectF mRectF;


    //背景颜色
    private int mOuterColor = Color.GRAY;
    //圆弧颜色
    private int mInterColor = Color.BLUE;
    //弧宽度
    private int mBorderWidth = 14; //10px

    //背景画笔
    private Paint mOuterPaint;
    //圆弧颜色
    private Paint mInnerPaint;

    //总流量
    private int mMaxStep = 0;
    //剩余流量
    private int mCurrentStep = 0;

    //是否使用渐变
    private boolean useGradient = true;
    //前景色起始颜色
    private int foreStartColor;
    //前景色结束颜色
    private int foreEndColcor;

    public CircleProgressView(Context context) {

        super(context);

        initPaint(context, null);

    }

    public CircleProgressView(Context context, @Nullable AttributeSet attrs) {

        super(context, attrs);

        initPaint(context, attrs);
        initAttrs(context, attrs);
        initVariable();

    }
    private void initAttrs(Context context, AttributeSet attrs){
        //获取xml里的属性值
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressView);
        mOuterColor = array.getColor(R.styleable.CircleProgressView_outerColor, mOuterColor);
        mInterColor = array.getColor(R.styleable.CircleProgressView_innerColor, mInterColor);
        mBorderWidth = (int) array.getDimension(R.styleable.CircleProgressView_borderWidth, mBorderWidth);
        foreStartColor = array.getColor(R.styleable.CircleProgressView_foreStartColor, Color.RED);
        foreEndColcor = array.getColor(R.styleable.CircleProgressView_foreEndColor, Color.BLUE);

        //释放资源
        array.recycle();
    }

    private void initVariable() {
        //初始化背景画笔
        mOuterPaint = new Paint();
        mOuterPaint.setAntiAlias(true);
        mOuterPaint.setColor(mOuterColor);
        mOuterPaint.setStrokeWidth(mBorderWidth);//width 是弧的内外扩散的
        mOuterPaint.setStyle(Paint.Style.STROKE);//Fill画笔实心,Stroke描边
        mOuterPaint.setStrokeCap(Paint.Cap.ROUND);

        //初始化圆弧画笔
        mInnerPaint = new Paint();
        mInnerPaint.setAntiAlias(true);
        mInnerPaint.setColor(mInterColor);
        mInnerPaint.setStrokeWidth(mBorderWidth);//width 是弧的内外扩散的
        mInnerPaint.setStyle(Paint.Style.STROKE);//Fill画笔实心,Stroke描边
        mInnerPaint.setStrokeCap(Paint.Cap.ROUND);
    }


    private void initPaint(Context context, AttributeSet attrs) {
        paint.setStrokeCap(Paint.Cap.ROUND);
        paint.setTextSize(textSize);
        paint.setStrokeWidth(strokeWidth);
        paint.setTextAlign(Paint.Align.CENTER);
//        paint.setColor(colorBackground);

    }

    public CircleProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

        super(context, attrs, defStyleAttr);

        initPaint(context, attrs);

    }

    @Override

    protected void onDraw(Canvas canvas) {

        super.onDraw(canvas);

        float endAngle = (float) mCurrentStep / mMaxStep * 180;
        Log.i(TAG,"mCurrentStep"+ mCurrentStep + "mMaxStep" + mMaxStep + "endAngle" + endAngle);
        drawCircle(startAngle, endAngle, canvas, paint);
        drawOut(canvas);

    }

    private void drawOut(Canvas canvas) {
        int center = getWidth() / 2;
        int radius = getWidth() / 2 - mBorderWidth / 2;

        RectF rectF = new RectF(center-radius, center-radius, center+radius, center+radius);
        //绘制背景圆弧
        canvas.drawArc(rectF, 180, 180, false, mOuterPaint);
        if (mMaxStep == 0) {
            return;
        }
        float sweepAngle = (float) mCurrentStep / mMaxStep;
        //绘制圆弧画笔
        canvas.drawArc(rectF, 180, sweepAngle * 180, false, mInnerPaint);

    }

    private void drawCircle(float startAngle, float endAngle, Canvas canvas, Paint paint) {

        for (float i = startAngle; i <= fullAngle - startAngle; i = i + perAngle) {
//-12.-6,0,6....180,186,192
//得出坐标
            int startM, startN, endM, endN, startX, startY, endX, endY;
            int startPaintRadius = innerRadius;
            int endPaintRadius = outRadius;
            float currentAngle = i;
            Log.i(TAG,"currentAngle: " + currentAngle + " startPaintRadius: " + startPaintRadius + " endPaintRadius: " +endPaintRadius + " i: " + i);
            if (i <= 0) {
                currentAngle = Math.abs(i);
            } else if (currentAngle > fullAngle) {
                currentAngle = i - fullAngle;
            }
//当前进度=结束进度
            if (i == endAngle) {
                startPaintRadius = innerRadius;
                endPaintRadius = outRadius ;
            }
//起始点
            double angleSin = Math.sin(Math.PI * (Math.abs(currentAngle) / fullAngle));
//起始点 高度 宽度
            startM = (int) (angleSin * startPaintRadius);
            startN = (int) Math.sqrt(Math.pow(startPaintRadius, 2) - Math.pow(startM, 2));
//结束点 高度 宽度
            endM = (int) (angleSin * endPaintRadius);
            endN = (int) Math.sqrt(Math.pow(endPaintRadius, 2) - Math.pow(endM, 2));
// Log.i(TAG, startM + "," + startN + "," + endM + "," + endN);
//获得起始点和结束点的坐标
            if (i < 0) {
//第三象限
                startX = centerX - startN;
                endX = centerX - endN;
                startY = centerY + startM;
                endY = centerY + endM;
                Log.i(TAG,"startX3 "+ startX + " endX3: "+ endX + " startY3: " + startY + "endY3: " + endY);
            } else if (i > fullAngle) {
//第二象限
                startX = centerX + startN;
                endX = centerX + endN;
                startY = centerY + startM;
                endY = centerY + endM;
                Log.i(TAG,"startX2 "+ startX + " endX2: "+ endX + " startY2: " + startY + "endY2: " + endY);
            } else {
                if (i < cutAngle) {

//第四象限
                    startX = centerX - startN;
                    endX = centerX - endN;
                    startY = centerY - startM;
                    endY = centerY - endM;
                    Log.i(TAG,"startX4 "+ startX + " endX4: "+ endX + " startY4: " + startY + "endY4: " + endY);
                } else {
//第一象限
                    startX = centerX + startN;
                    endX = centerX + endN;
                    startY = centerY - startM;
                    endY = centerY - endM;
                    Log.i(TAG,"startX1 "+ startX + " endX1: "+ endX + " startY1: " + startY + "endY1: " + endY);
                }
            }
//设置线条绘制颜色
            if (i <= endAngle) {
                paint.setShader(gradient);
//                paint.setColor(colorProgress);
            } else {
                paint.setShader(null);
                paint.setColor(colorBackground);
            }
            canvas.drawLine(startX, startY, endX, endY, paint);
        }
    }


    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        //画笔设置渐变色
        initRect(w,h);

        if (useGradient) {
            LinearGradient gradient = new LinearGradient(0, 0, w, h, foreStartColor, foreEndColcor, Shader.TileMode.CLAMP);
            this.gradient = gradient;
            mInnerPaint.setShader(gradient);
        } else {
            mInnerPaint.setColor(mInterColor);

        }
    }

    private void initRect(int width, int height) {
        mRectF = new RectF(0, 0, width, height);
        paint.setShader(new LinearGradient(0, 0, mRectF.right, 0,
                Color.GREEN, Color.RED, Shader.TileMode.CLAMP));
    }

    @Override

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        setMeasuredDimension(width > height ? height : width, width > height ? height : width);


        innerRadius = (getMeasuredWidth() - lineLength * 2 ) / 2 ;
        outRadius = 11 + innerRadius;
        Log.i(TAG,"内圈半径:" + innerRadius + ",外圈半径:" + outRadius);
        centerX = 187 + maxLineLength;
        centerY = 187 + maxLineLength;
        Log.i(TAG,"中心坐标:(x=" + centerX + ",y=" + centerY + ")");
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        if (heightMode == MeasureSpec.AT_MOST) {
            double angleSin = Math.sin(Math.PI * (Math.abs(startAngle) / fullAngle));
            int endPaintRadius = outRadius + maxLineLength;
            height = (int) (endPaintRadius + angleSin * endPaintRadius);
            setMeasuredDimension(widthMeasureSpec, height);
        }
    }

    public synchronized void setStepMax(int mMaxStep) {
        this.mMaxStep = mMaxStep;
    }

    public synchronized void setCurrentStep(int mCurrentStep) {
        this.mCurrentStep = mCurrentStep;
        invalidate();
    }

}

四.使用

1.UI绘制
   <com.text.ui.CircleProgressView
            android:id="@+id/circle_progress"
            android:layout_width="374px"
            android:layout_height="374px"
            android:layout_marginTop="@dimen/y34"
            android:layout_marginStart="@dimen/x17"
            app:foreStartColor="#7D78FF"
            app:foreEndColor="#00DFFF"
            app:outerColor= "@color/btn_weak_color" />
2.代码使用
    circleProgressView.setStepMax(24);
    circleProgressView.setCurrentStep(12);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值