CircleShape渐变颜色圆环

设计思路

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

知识点

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271

推荐阅读更多精彩内容