CircleShape渐变颜色圆环

作者: 琳子baby | 来源:发表于2018-06-12 11:41 被阅读87次

    设计思路

    通过自定义控件实现。将整个圆环拆分成一个个的小圆弧,每个小圆弧画笔的色值不一样,每个圆弧画笔的色值都是起始色值和终止色值的中间过渡色,由起始色值逐渐向终止色值靠拢,最后形成渐变颜色的圆环。

    知识点

    1、自定义控件

    自定义控件分为三种:继承控件,即在现有控件直接简单修改;组合控件,即GroupView;自定义View。具体自定义控件的细节,这里不再细说,可以参阅网上资料。

    2、画笔

    画笔类型(setStyle)分为三种:STROKE只绘制图形轮廓,FILL只绘制图形内容,FILL_AND_STROKE既绘制轮廓也绘制内容;我们采用的是STROKE,也就是描边。

    笔刷样式(setStrokeCap)分为三种:Round圆形冒;SQUARE方形冒;BUTT无冒。这里需要注意,冒的意思就是多出一部分,所以我们采用的是BUTT,下面会详细说明。

    画笔宽度(setStrokeWidth)

    3、画图

    RectF:RectF有四个参数(float left, float top, float right, float bottom)

    1.jpg

    drawArc:画弧,主要关注startAngle、sweepAngle两个参数


    2.jpg

    实现

    (1)onMeasure设定画大小

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
         mMeasureWidth = getMeasuredWidth()
         mMeasureHeight = getMeasuredHeight();
         if (pRectF == null) {
             float halfProgressWidth = progressWidth / 2;
             pRectF = new RectF(halfProgressWidth + getPaddingLeft(),
                        halfProgressWidth + getPaddingTop(),
                        mMeasureWidth - halfProgressWidth - getPaddingRight(),
                        mMeasureHeight - halfProgressWidth - getPaddingBottom());
            }
        }
    
    

    (2)onDraw确定怎么画,这里主要看一下drawProgress,整个圆弧由多个小圆弧组成,通过获取过渡色设置笔刷颜色,笔刷颜色从起始色值开始,每增加一度都向终止色值渐变

    private void drawProgress(Canvas canvas) {
         for (int i = 0, end = (int) (curProgress * unitAngle); i < end; i++) {
             progressPaint.setColor(getGradient(i / (float) end, progressStartColor, progressEndColor));
             canvas.drawArc(pRectF,
                     startAngle + i,
                     2,
                     false,
                     progressPaint);
            }
        }
    
    

    (3)获取过渡色的方法

    public int getGradient(float fraction, int startColor, int endColor) {
         if (fraction > 1) fraction = 1;
         int alphaStart = Color.alpha(startColor);
         int redStart = Color.red(startColor);      
         int blueStart = Color.blue(startColor);
         int greenStart = Color.green(startColor);
         int alphaEnd = Color.alpha(endColor);
         int redEnd = Color.red(endColor);      
         int blueEnd = Color.blue(endColor);
         int greenEnd = Color.green(endColor);
         int alphaDifference = alphaEnd - alphaStart;
         int redDifference = redEnd - redStart;
         int blueDifference = blueEnd - blueStart;
         int greenDifference = greenEnd - greenStart;
         int alphaCurrent = (int) (alphaStart + fraction * alphaDifference);
         int redCurrent = (int) (redStart + fraction * redDifference);
         int blueCurrent = (int) (blueStart + fraction * blueDifference);
         int greenCurrent = (int) (greenStart + fraction * greenDifference);
         return Color.argb(alphaCurrent, redCurrent, greenCurrent, blueCurrent);
        }
    
    

    (4)问题解决

    画圆环的过程中会遇到一个问题,上面提到的笔刷样式的选择,下面是三种笔刷的示意图:

    Paint.Cap.ROUND 头尾多出了一块圆形笔帽

    3.png

    Paint.Cap.SQUARE 头尾多出了一块方形笔帽

    4.png

    Paint.Cap.BUTT 头尾不多出笔帽,但是每个小圆环中间有空隙

    5.png

    解决方案: sweepAngle比下一次的startAngle多一点。

    6.png

    (5)后续拓展 通过showAnim来控制圆环动效

    使用

    1、在layout中设置width、height、画笔宽度

    <com.component.circleshape.CircleShape
        android:id="@+id/circle_shape"
        android:layout_width="320dp"
        android:layout_height="320dp"
        android:layout_gravity="center"
        a:pr_progress_width="30dp" />
    
    

    2、在类中设置progress、背景色、进度起始色、进度终止色

    CircleShape mPR = findViewById(R.id.circle_shape);
    mPR.setProgress(60);
    mPR.setColor(R.color.bgColor,R.color.progressStartColor, R.color.progressEndColor);
    

    源码下载:https://github.com/Sophia216/CircleShape

    相关文章

      网友评论

      本文标题:CircleShape渐变颜色圆环

      本文链接:https://www.haomeiwen.com/subject/huyleftx.html