先来一张效果图预览
代码其实很简单,鄙人处于研究阶段,有更好的建议欢迎指出。
实现自定义view第一步继承view类,
然后画图的渲染顺序为先执行onMesure方法计算view的宽高,这里把整个view处理成一个正方形,其它图形的有待研究
先把全局变量设置出来,以便不影响思维顺序
private int viewWidth = 0;
private int viewHeight = 0;
private float contentPadding = 0f;//默认边距
private float defaultPadding = 5f;
private float colorCircleWidth = 30f;//默认弧形宽度
float startRadian = 180;//起始角度水平左边开始
private int backGroundColor = 0;
List> circleNumList;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Log.e("onMeasure", "onMeasure");
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
viewWidth = getWidth();
viewHeight = getHeight();
int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
// 在wrap_content的情况下默认长度为200dp
int minSize = 0;
if (widthSpecSize > heightSpecSize) {
minSize = heightSpecSize;
} else if (widthSpecSize < heightSpecSize) {
minSize = widthSpecSize;
}
// wrap_content的specMode是AT_MOST模式,这种情况下宽/高等同于specSize
// 查表得这种情况下specSize等同于parentSize,也就是父容器当前剩余的大小
// 在wrap_content的情况下如果特殊处理,效果等同martch_parent
if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST) {
setMeasuredDimension(minSize, minSize);
viewWidth = viewHeight = minSize;
} else if (widthSpecMode == MeasureSpec.AT_MOST) {
setMeasuredDimension(minSize, heightSpecSize);
viewWidth = minSize;
viewHeight = heightSpecSize;
} else if (heightSpecMode == MeasureSpec.AT_MOST) {
setMeasuredDimension(widthSpecSize, minSize);
viewWidth = widthSpecSize;
viewHeight = minSize;
}
}
viewWidth和viewHeight为一个全局的变量,用于设置绘图的背景
计算完view宽高后执行onDraw方法进行渲染我们想要的图形样式
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Log.e("onDraw", "onDraw");
//设置背景颜色
Paint bgPaint = new Paint();
bgPaint.setColor(backGroundColor);
canvas.drawRect(0, 0, viewWidth, viewHeight, bgPaint);
Paint mArcPaint = new Paint();
mArcPaint.setAntiAlias(true);
mArcPaint.setColor(Color.parseColor("#ff6600"));
mArcPaint.setStyle(Paint.Style.STROKE);
mArcPaint.setStrokeWidth(colorCircleWidth);//线宽
drawableCircle(canvas, mArcPaint, circleNumList);
}
private void drawableCircle(Canvas canvas, Paint circlePaint, List> circleNumList) {
if (defaultPadding * circleNumList.size() > (viewWidth / 2 - defaultPadding)) {
colorCircleWidth = (viewWidth / 2 - defaultPadding) / circleNumList.size();
}
float circleWidth = defaultPadding;
for (int j = 0; j < circleNumList.size(); j++) {
RectF mRectF = new RectF(circleWidth, circleWidth, viewWidth - circleWidth, viewHeight - circleWidth);
List circleBeanList = circleNumList.get(j);
startRadian = 180;
float scalRadian = 0;
for (int i = 0; i < circleBeanList.size(); i++) {
CircleBean circleBean = circleBeanList.get(i);
scalRadian = circleBean.getRadianValue();
String color = circleBean.getRadianColor();
circlePaint.setColor(Color.parseColor(color));
if ((startRadian + scalRadian) >= (360 + 180)) {//弧度总和超过一圈在起始点结束
scalRadian = ((360 + 180) - startRadian);
}
canvas.drawArc(mRectF, startRadian, scalRadian, false, circlePaint);
startRadian += circleBean.getRadianValue();
}
circleWidth += colorCircleWidth + 1;
}
}
(备注)当一层圆的数据超过360弧度时只 会显示一个圆的范围,超出360度的值不显示
bean里面有两个参数可供使用
public class CircleBean {
private float radianValue;//每段弧度的值
private String radianColor;//每段弧度的颜色
public float getRadianValue() {
return radianValue;
}
public void setRadianValue(float radianValue) {
this.radianValue = radianValue;
}
public String getRadianColor() {
return radianColor == null ? "" : radianColor;
}
public void setRadianColor(String radianColor) {
this.radianColor = radianColor;
}
}
public CircleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray custorm = context.obtainStyledAttributes(attrs, R.styleable.circle_view_styleable);
contentPadding = custorm.getDimension(R.styleable.circle_view_styleable_viewPadding, 0f);
colorCircleWidth = custorm.getDimension(R.styleable.circle_view_styleable_circleWidth, 30f);
backGroundColor = custorm.getColor(R.styleable.circle_view_styleable_backGroundColor, Color.parseColor("#ffffff"));
defaultPadding = colorCircleWidth / 2 + contentPadding;
custorm.recycle();
}
做完项目剩余时间来写的,如果 不是很完整可以下载工程来看。(工程采用as工具编写)
项目免费下载地址点击打开链接