自定义View之—渐变进度条
发表于|更新于
|阅读量:
最近项目中用到渐变圆环进度条,自己也写了一下,用到一些知识,以前没有用过,使用过程中有一些问题,在此做一下笔记。
渐变颜色其实用到的是颜色数组,然后根据数组计算来的,当然计算是Android系统进行的,不需要我们手动计算,我们只需要设置颜色数组和颜色值对应位置即可。画圆形渐变用到一个属性:SweepGradient,他的父类是一个Shader,
由官方文档看到他有两个构造函数:
1 2 3
| SweepGradient(float cx, float cy, int color0, int color1) SweepGradient(float cx, float cy, int colors[], float positions[])
|
- cx:要画的圆环的中心点x坐标;
- cy:要画的圆环的中心点y坐标;
- color0:起始颜色值;
- color1:结束颜色值;
- colors[]:颜色数组;
- positions[]:对应颜色值的位置,与颜色值数组个数相等,里面的值均为(0–1)的数字。
先看一张效果图(图一):
这就是一张渐变圆环图,上面的箭头和数字后面解释。
我们主要研究第二个构造函数,颜色数组和颜色位置的使用方法。
首先看一个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
public class CircleGradientProgressbar extends View {
private final static int DURATION = 3000; private int mWidth; private int mHeight; private int mDiam;
private int mColorGreen; private int mColorYellow; private int mColorRed;
private final float mMaxProgress = 100f; private int mProgress = 80;
private int mCurrentProgress = 100; private int mProgressStrokeWidth = 10; private Paint mCirclePaint; private Paint mProgressPaint; private Shader mProgressShader;
private RectF mProgressOval;
private ValueAnimator mAnimator;
public CircleGradientProgressbar(Context context) { this(context, null); }
public CircleGradientProgressbar(Context context, AttributeSet attrs) { super(context, attrs); init(); }
private void init() {
mColorGreen = getResources().getColor(R.color.mx_circle_progressbar_green); mColorYellow = getResources().getColor(R.color.mx_circle_progressbar_orange); mColorRed = getResources().getColor(R.color.mx_circle_progressbar_red);
mProgressOval = new RectF();
mCirclePaint = new Paint(); mCirclePaint.setAntiAlias(true); mCirclePaint.setColor(Color.GRAY);
mProgressPaint = new Paint(); mProgressPaint.setAntiAlias(true);
mProgressPaint.setStyle(Paint.Style.STROKE);
mAnimator = ValueAnimator.ofFloat(0, 1f);
mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float percent = (float) animation.getAnimatedValue(); if (percent > 0) { mCurrentProgress = (int) (mProgress * percent); postInvalidate(); } } });
}
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mWidth = getWidth(); mHeight = getHeight(); mDiam = Math.min(mWidth, mHeight); mProgressStrokeWidth = mDiam / 6; drawCircle(canvas); drawSweepProgressBar(canvas, mWidth / 2, mHeight / 2); }
private void drawCircle(Canvas canvas) { canvas.drawArc(mProgressOval, 0, 360, false, mCirclePaint); }
private void drawSweepProgressBar(Canvas canvas, int cx, float cy) {
mProgressOval.top = cy - mDiam / 4; mProgressOval.left = cx - mDiam / 4; mProgressOval.bottom = cy + mDiam / 4; mProgressOval.right = cx + mDiam / 4;
int colorSweep[] = {mColorGreen, mColorYellow, mColorRed}; float position[] = {0f,0.5f,0.7f}; mProgressShader = new SweepGradient(cx, cy, colorSweep, position); mProgressPaint.setShader(mProgressShader); mProgressPaint.setStrokeWidth(mProgressStrokeWidth); canvas.drawArc(mProgressOval, 0, ((float) mCurrentProgress / mMaxProgress) * 360, false, mProgressPaint);
}
public void setProgress(int progress) { this.mProgress = progress; if (mAnimator != null && progress > 0) { if (mAnimator.isRunning()) { return; } mAnimator.setDuration((long) (DURATION / mMaxProgress * progress)); mAnimator.start(); } } }
|
效果图如下:
此时的颜色数组和位置参数为:
1 2
| int colorSweep[] = {mColorGreen, mColorYellow, mColorRed}; float position[] = {0f,0.5f,0.7f};
|
下面我们更改一下颜色值的位置:
1 2
| int colorSweep[] = {mColorGreen, mColorYellow, mColorRed}; float position[] = {0.25f,0.5f,0.75f};
|
效果图如下:
对比上面两个图片我们看到随着第一个位置的值的增大,第一个颜色值的渐变色开始位置也在向后移动。此时我们画圆环是从0度开始的,也就是3点钟的位置开始,顺时针开始画圆环。第一个颜色绿色也是从这个位置开始的。那么我们看看如果我改变开始画的位置,有什么变化吗?
我用上面第二组的数据,然后只改变画圆环的初始位置:
1 2 3
| int colorSweep[] = {mColorGreen, mColorYellow, mColorRed}; float position[] = {0.25f,0.5f,0.75f}; canvas.drawArc(mProgressOval, 0, ((float) mCurrentProgress / mMaxProgress) * 360, false, mProgressPaint);
|
效果图如下:
显示效果和上面一个是一样的,只是运行时你会发现,圆环是从(图一)0.75那个位置开始顺时针画的,并且开始画的颜色是红色的,由此判断,第一个颜色值是用(图一)0的那个位置顺时针开始计算的,那么如果我想从0.75那个位置开始画并且颜色从绿的开始怎么画,那你需要将开始画的角度改为:-90,然后更改颜色数组和颜色位置数组:
1 2 3
| int colorSweep[] = {mColorGreen, mColorGreen, mColorYellow, mColorRed, mColorGreen, mColorGreen}; float position[] = {0.1f, 0.25f, 0.5f, 0.751f, 0.75f, 1f}; canvas.drawArc(mProgressOval, -90, ((float) mCurrentProgress / mMaxProgress) * 360, false, mProgressPaint);
|
效果图如下:
此时我们看到,绿色是从(图一)0.75位置开始的,并且圆环也是从这个位置开始画的,但是此时我的颜色值和位置增加了,主要是后面部分,倒数第二个颜色值是绿色,对应位置是0.75,也是就分段设置颜色值,0.75的位置为绿色,最后一个也是绿色,则说明从0.75之后到1的位置都是绿色,然后0后面的颜色根据位置数组第一个参数开始计算,如果角度不是0就要按照这个计算进行调整。
另外,最后一个例子中相同颜色设置了多个,这个是调节渐变和纯色位置的,也就是相同颜色位置间的颜色是纯色的,不同颜色值中间的颜色是过度的,自己可以调节一下掌握以下技巧。
Github地址:https://github.com/yuchuangu85/OpenSource_MX
Android开发群:192508518
微信公众账号:Code-MX
注:本文原创,转载请注明出处,多谢。