一、写在前面的话
今天做了个控件,觉得还挺漂亮,就拿出来给大家分享一下,主要为了给大家介绍一下ValueAnimator这个动画,确实也没啥好说的,网上一堆教程,还是说说说画这个动画好了。
二、需求分析
刚拿到需求,我们分析一下。控件有两道圆弧,第一道上面有数据段,第二段是具体数值的指示段。
数值变换的时候,需要平滑过渡,不能突兀。
三、开始画。
1、画圆弧
private void drawArc(Canvas canvas) {
mBgPaint.setStrokeWidth(mProgressSize);
canvas.drawArc(mProgressSize * lineSize, mProgressSize * lineSize, mWidth - mProgressSize * lineSize, mHeight - mProgressSize * lineSize, 150, 240, false, mBgPaint);
//画推荐度数
canvas.drawArc(mProgressSize * lineSize, mProgressSize * lineSize, mWidth - mProgressSize * lineSize, mHeight - mProgressSize * lineSize, 150 + lowProgress * 240 / 100, (highProgress - lowProgress) * 240 / 100, false, mProgressPaint);
//画推荐度数的值
int r = mWidth / 2 - mProgressSize;
int x = getArcX(150 + lowProgress * 240 / 100, r);
int y = getArcY(150 + lowProgress * 240 / 100, r);
int x2 = getArcX(150 + highProgress * 240 / 100, r);
int y2 = getArcY(150 + highProgress * 240 / 100, r);
if (x < mWidth / 2) {
x = x - 13;
} else {
y = y + 7;
x = x - 3;
}
if (x2 < mWidth / 2) {
x2 = x2 - 13;
} else {
x2 = x2 - 3;
y2 = y2 + 7;
}
canvas.drawText(stringLowProgress, x, y, mTextPaint);
canvas.drawText(stringHighProgress, x2, y2, mTextPaint);
mBgPaint.setStrokeWidth(mProgressSize / 3);
canvas.drawArc(mProgressSize * offset, mProgressSize * offset, mWidth - mProgressSize * offset, mHeight - mProgressSize * offset, 150, 240, false, mBgPaint);
}
为什么会/100呢,因为这里我把进度放大了一百倍,为了值的变化更流畅。
2、画刻度
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void drawLine(Canvas canvas) {
canvas.drawArc(mProgressSize * lineSize, mProgressSize * lineSize, mWidth - mProgressSize * lineSize, mHeight - mProgressSize * lineSize, 150 + 6 - 1, 2, false, mWhitePaint);
for (int i = 1; i < 10; i++) {
canvas.drawArc(mProgressSize * lineSize, mProgressSize * lineSize, mWidth - mProgressSize * lineSize, mHeight - mProgressSize * lineSize, 150 + 24 * i - 1, 2, false, mWhitePaint);
}
canvas.drawArc(mProgressSize * lineSize, mProgressSize * lineSize, mWidth - mProgressSize * lineSize, mHeight - mProgressSize * lineSize, 30 - 6 - 1, 2, false, mWhitePaint);
}
这里的刻度我们画一小段白色的圆弧,大家可以根据自己的要求改一下。
3、画指针
private void drawProgress(Canvas canvas) {
//计算当前的角度
int angle = 150 + mProgress * 240 / mMaxProgress;
int r = mWidth / 2 - mProgressSize * offset;
int cx = getArcX(angle, r);
int cy = getArcY(angle, r);
canvas.drawCircle(cx, cy, 4, mProgressPaint);
//圆外一点的坐标
int x = getArcX(angle, r + 35);
int y = getArcY(angle, r + 35);
//控制点1
int co1x = getArcX(angle - 4, r + 5);
int co1y = getArcY(angle - 4, r + 5);
//控制点2
int co2x = getArcX(angle + 4, r + 5);
int co2y = getArcY(angle + 4, r + 5);
path.reset();
path.moveTo(co1x, co1y);
path.lineTo(co2x, co2y);
path.lineTo(x, y);
path.lineTo(co1x, co1y);
canvas.drawPath(path, mSmallWhitePaint);
canvas.drawCircle(cx, cy, 1, mWhitePaint);
}
4、指针动画
// /**
// * 进度显示动画效果初始化
// */
private void initValueAnimator() {
valueAnimator = new ValueAnimator();
valueAnimator.setInterpolator(interpolator);
valueAnimator.addUpdateListener(new ValueAnimatorListenerImp());