如上图的圆形的progressbar,不仅带有渐变色,还有在起止点都有一个小圆点,那么怎么实现呢?
首先,考虑这肯定得自定义了;
然后看他的组成部分,有三个,底下亮灰色的圆环,一个带渐变色的弧线,还有弧线起止点的圆点;
最后就是继承View,使用paint开始画了,以下是源码,一些自定义属性就不上传了,就三个,自己定义以下就好:
package com.terminus.component.views;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import com.terminus.component.R;
/**
* Created by Qile on 2018/12/12
*/
public class CustomProgress extends View {
private Paint mPaint;
private Paint mPointPaint;
private Paint mCirclePaint;
private int startColor;
private int centerColor;
private int endColor;
private int offSet = 40;
private float pointX;
private float pointY;
private float pointR = 10;
private float mSweepAngle = 180;
private float mStartAngle = -90;
public CustomProgress(Context context) {
this(context, null);
}
public CustomProgress(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomProgress(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CustomProgress);
startColor = ta.getColor(R.styleable.CustomProgress_progressCusStartColor, context.getResources().getColor(R.color.dark_blue));
centerColor = ta.getColor(R.styleable.CustomProgress_progressCusCenterColor, context.getResources().getColor(R.color.white));
endColor = ta.getColor(R.styleable.CustomProgress_progressCusEndColor, context.getResources().getColor(R.color.green));
ta.recycle();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPointPaint = new Paint();
mPointPaint.setAntiAlias(true);
mCirclePaint = new Paint();
mCirclePaint.setAntiAlias(true);
}
private int width;
private int height;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = measureDimension(200, widthMeasureSpec);
height = measureDimension(200, heightMeasureSpec);
setMeasuredDimension(width, height);
}
private int measureDimension(int defaultValue, int measureSpec) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
result = specSize;
} else {
result = defaultValue;
if (specMode == MeasureSpec.AT_MOST) {
result = Math.min(defaultValue, specSize);
}
}
return result;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(10);
int[] colors = {startColor, centerColor, endColor};
mPointPaint.setColor(startColor);
mPointPaint.setStyle(Paint.Style.FILL);
mCirclePaint.setColor(Color.LTGRAY);
mCirclePaint.setStyle(Paint.Style.STROKE);
mCirclePaint.setStrokeWidth(10);
RectF rectF = new RectF(offSet, offSet, width - offSet, height - offSet);
LinearGradient lg = new LinearGradient(offSet, offSet, width - offSet, height - offSet, colors, null, Shader.TileMode.MIRROR);
mPaint.setShader(lg);
canvas.drawCircle(width / 2, height / 2, width / 2 - offSet, mCirclePaint);
canvas.drawArc(rectF, mStartAngle, mSweepAngle, false, mPaint);
canvas.drawCircle(getPointX(width / 2, mStartAngle, width / 2 - pointR),
getPointY(height / 2, mStartAngle, width / 2 - pointR), pointR, mPointPaint);
mPointPaint.setColor(endColor);
pointX = getPointX(width / 2, mSweepAngle + mStartAngle, width / 2 - pointR);
pointY = getPointY(height / 2, mSweepAngle + mStartAngle, width / 2 - pointR);
canvas.drawCircle(pointX, pointY, pointR, mPointPaint);
}
private float getPointY(int circleY, float sweepAngle, float circleR) {
return circleY + circleR * (float) Math.sin(sweepAngle * Math.PI / 180);
}
private float getPointX(int circleX, float sweepAngle, float circleR) {
return circleX + circleR * (float) Math.cos(sweepAngle * Math.PI / 180);
}
public void setProgress(int progress, int max) {
setProgressWithAngle(-90f, progress, max);
}
public void setProgressWithAngle(float startAngle, int progress, int max) {
mStartAngle = startAngle;
mSweepAngle = 360 * (progress / max);
invalidate();
}
}