android: 一次自绘控件的体验
程序员文章站
2022-05-28 19:40:40
...
一个盆友在 qq 上面给我一个截图,问我有没有见过这种效果。我一看,貌似不太难,虽然我并不熟悉自定义控件,但是网上的教程很多,于是决定实现一下。
这个就是给我的截图。不是很清晰,也不完整。但是重点突出出来了。
于是,我看了看 HenCoder 的教程1,决定实现一下。(当然,实现期间,也翻阅了一下其他人的博客)
我实现的效果如下:
大体实现贴一下:
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
this.mWidth = w;
this.mHeight = h;
min = Math.min(mWidth, mHeight);
tableList = DynamicData.getViewSource();
paint = new Paint();
LogUtils.w(tableList);
oval = new RectF(0, 0, min, min);
icon = new RectF();
diffLeft = min / 10;
diffRight = diffLeft;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawLeft(canvas);
iconLength = 1f * min / 17;
int height = (int) (iconLength / 2);
for (Table t : tableList) {
float left = min + diffLeft;
float right = left + iconLength;
float top = 0;
float bottom = top + iconLength;
paint.setColor(t.color);
icon.set(left, height + top, right, height + bottom);
canvas.drawRect(icon, paint);
paint.setTextSize(iconLength);
paint.setColor(Color.BLACK);
canvas.drawText(t.name + "\t" + (int) t.percent + "%",
right + diffRight, height + bottom, paint);
height += iconLength * 3;
}
}
private void drawLeft(Canvas canvas) {
paint.setColor(Color.parseColor("#dbdbdb"));
canvas.drawRect(oval, paint);
int start = 180;
for (Table t : tableList) {
float angle = (float) t.percent / 100 * 360;
paint.setColor(t.color);
paint.setStrokeCap(Paint.Cap.ROUND);
scaleOval(t.scale);
canvas.drawArc(oval, start, angle,
true, paint);
start += angle;
}
paint.setColor(Color.WHITE);
canvas.drawCircle(1f * min / 2, 1f * min / 2, min * 1f / 12, paint);
scaleOval(1); // 要加这一句,不然 onStop 后再进来就变小了
}
private void scaleOval(float scale) {
oval.set(0, 0, min, min);
float left = 1f * min * (1 - scale) / 2;
float top = 1f * min * (1 - scale) / 2;
float right = 1f * min * scale + left;
float bottom = 1f * min * scale + top;
oval.set(left, top, right, bottom);
}
嗯,里面的逻辑不复杂,主要是对系统 api 的调用,然后计算一下,每次画的起始位置。
其实,这种东西,我之前看到也会害怕,但是,真的很一般,不难的。
不过,这里还是有需要优化的地方,比如最小尺寸,如果设置成 wrap_conent 怎么处理,等等。我这里的逻辑全部是 onDraw()
需要的,其他的,我没有去实现。
如果想看完整源码:献丑了,戳我。。。