Anroid 自定义View 实现多个颜色的圆环

实现效果(灰色是背景色):

1.attrs:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="XRingView">
        <attr name="ring_color0" format="color"/>
        <attr name="ring_color1" format="color"/>
        <attr name="ring_color2" format="color"/>
        <attr name="ring_color3" format="color"/>
        <attr name="ring_color4" format="color"/>
        <attr name="ring_max_progress" format="float"/>
        <attr name="ring_color0_progress" format="float"/>
        <attr name="ring_color1_progress" format="float"/>
        <attr name="ring_color2_progress" format="float"/>
        <attr name="ring_color3_progress" format="float"/>
        <attr name="ring_color4_progress" format="float"/>
        <attr name="ring_size" format="dimension"/>
        <attr name="ring_isRank" format="boolean"/><!-- 是否排序-->
        <attr name="ring_progress_background" format="color"/>
    </declare-styleable>

</resources>

2.JAVA代码:

/**
 * created by: Eroch
 * time: 2020/3/13
 * introduce: 自定义圆环,最多支持同时5个颜色,index越大越上层,(如有需要,可自行修改代码)
 */
public class XRingView extends View {

    float topAndBottomOffset;//XRingView的宽高
    private float size;//进度条的的宽度
    private Paint paint;//画笔
    private float density;//当前手机屏幕密度
    private Activity mActivity;
    private float[] progressS;//当前所有的进度
    private int[] colorS;//当前所有的进度条的颜色
    private float component;//平均值

    public XRingView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        this.mActivity = (Activity) context;
        DisplayMetrics metrics = new DisplayMetrics();
        mActivity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
        density = metrics.density;
        paint = new Paint();
        paint.setStrokeCap(Paint.Cap.ROUND);//设置笔端样式
        paint.setAntiAlias(true);//抗锯齿
        paint.setDither(true);//抗抖动
        paint.setFilterBitmap(false);//过滤bitmap,提高绘制速度
        paint.setStyle(Paint.Style.STROKE);//设置画笔的样式
        paint.setStrokeWidth(2);
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.XRingView);
        if (array != null){
            size = array.getDimension(R.styleable.XRingView_ring_size, 3 * density);
            paint.setStrokeWidth(size*density);
            int color0 = array.getColor(R.styleable.XRingView_ring_color0,0);
            int color1 = array.getColor(R.styleable.XRingView_ring_color1,0);
            int color2 = array.getColor(R.styleable.XRingView_ring_color2,0);
            int color3 = array.getColor(R.styleable.XRingView_ring_color3,0);
            int color4 = array.getColor(R.styleable.XRingView_ring_color4,0);
            int background = array.getColor(R.styleable.XRingView_ring_progress_background,Color.parseColor("#10000000"));
            paint.setColor(background);
            colorS = new int[]{color0,color1,color2,color3,color4};
            float progress0 = array.getFloat(R.styleable.XRingView_ring_color0_progress,0);
            float progress1 = array.getFloat(R.styleable.XRingView_ring_color1_progress,0);
            float progress2 = array.getFloat(R.styleable.XRingView_ring_color2_progress,0);
            float progress3 = array.getFloat(R.styleable.XRingView_ring_color3_progress,0);
            float progress4 = array.getFloat(R.styleable.XRingView_ring_color4_progress,0);
            float maxProgress = array.getFloat(R.styleable.XRingView_ring_max_progress, 0);
            component = 360 / maxProgress;
            progressS = new float[]{progress0 *component, progress1*component, progress2*component, progress3*component, progress4*component};
            boolean isRank = array.getBoolean(R.styleable.XRingView_ring_isRank, false);//是否需要防止进度大的把进度小的盖住,排一下序号
            if (isRank) {
                //冒泡
                for (int i = 0; i < progressS.length - 1; i++) {
                    for (int j = 0; j < progressS.length - 1-i; j++) {
                        if (progressS[j] > progressS[j + 1]) {
                            float temp = progressS[j];
                            int color = colorS[j];
                            progressS[j] = progressS[j + 1];
                            colorS[j] = colorS[j +1];
                            progressS[j + 1] = temp;
                            colorS[j + 1] = color;
                        }
                    }
                }
            }
        }
        array.recycle();
    }

    //测量XRingView的宽高
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //wrap_content:-2
        //match_parent:-1
        int wi = getLayoutParams().width;
        int he =getLayoutParams().height;
        int width;
        if (wi > 0 || he > 0){
            width = he > wi ? he : wi;
        }else {
            width = (int) ((size * 2) + (10 * density));
        }
        float wh = ((wi>>1) - ((int)size>>1)) * density;
        topAndBottomOffset = wh -((int)size>>1);(>>1是除以2的一次方,>>2是除以2的二次方,>>3是除以2的3次方,不理解的去看一下位移运算符)
        setMeasuredDimension(width,width);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //270°是12点钟的位置
        //四个参数分别是:左 上 右 下 起始度数 需要执行多少度数 是否铺满(true:画出来的是扇形或圆形 false:画出来的是圆环或弧) 画笔
        canvas.drawArc( size,size,topAndBottomOffset,topAndBottomOffset,270,360,false,paint);

        //遍历数据,画出圆弧
        for (int i = progressS.length-1; i >0 ; i--) {
            if (progressS[i] != 0){
                paint.setColor(colorS[i]);
                canvas.drawArc( size,size,topAndBottomOffset,topAndBottomOffset,270,progressS[i],false,paint);
            }
        }
    }

}

end......

注意:这有个bug,就是XRing在XML里使用的时候,layout_width必须设置固定的值,至于是什么原因我不得而知,如有大佬知道,请留言指点,感谢感谢!

猜你喜欢

转载自blog.csdn.net/qq_41873558/article/details/104877625