前一段时间看一个学习效率的问题,发现自己的学习效率的确不高,写博客主要是为了加深映像,然后的在写的时候希望能够进一步能够理解。给大家看一张图
图片里面有一项:教授给他人 学习内容的留存率最大为90%
1.首先看下效果图,效果很简单
2. 实现思路
这个控件是由三部分组成的,分别是中间的文字,包括文字的圆圈,在加上最外层的圆环就可以了。
3.看一下自定义的View
public class SweepView extends View {
/** 圆心得坐标 */
private int mCircleXY;
/**外层圈子的宽度*/
private int circleWidth;
private int radius;
private RectF mArcRectF;
private Paint textPaint;
private Paint arcPaint;
private Paint circlePaint;
private String mShowText = "show skills";
/** 滑过的角度 */
private int sweepAngle = 270;
/**圈子里面文字的大小*/
private int circleTextColor;
/**圆圈的背景颜色*/
private int circleBackground;
/**圆圈的文字大小*/
private int circleTextSize;
public SweepView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
TypedArray typeArray = context.getResources().obtainAttributes(attrs, R.styleable.CircleView);
circleWidth = (int) typeArray.getDimension(R.styleable.CircleView_circleWidth, 200);
circleBackground = typeArray.getColor(R.styleable.CircleView_circleBackground,Color.BLUE);
circleTextColor = typeArray.getColor(R.styleable.CircleView_circleTextColor,Color.YELLOW);
circleTextSize = circleBackground = (int) typeArray.getDimension(R.styleable.CircleView_circleTextSize, 30);
mCircleXY = circleWidth / 2;
radius = circleWidth / 4;
mArcRectF = new RectF((float) (circleWidth * 0.15),
(float) (circleWidth * 0.15),
(float) (circleWidth * 0.85),
(float) (circleWidth * 0.85));
textPaint = new Paint();
textPaint.setColor(circleTextColor);
textPaint.setTextSize(circleTextSize);
textPaint.setTextAlign(Paint.Align.CENTER);
arcPaint = new Paint();
arcPaint.setStyle(Paint.Style.STROKE);
arcPaint.setColor(Color.YELLOW);
arcPaint.setStrokeWidth(45);
circlePaint = new Paint();
circlePaint.setColor(Color.BLUE);
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
canvas.drawArc(mArcRectF, 270, sweepAngle, false, arcPaint);
canvas.drawCircle(mCircleXY, mCircleXY, radius, circlePaint);
textPaint.measureText(mShowText, 0, mShowText.length());
float baseLine = (circleWidth / 2)
- ((textPaint.descent() + textPaint.ascent()) / 2);
canvas.drawText(mShowText, 0, mShowText.length(), mCircleXY, baseLine,
textPaint);
}
public void setSweepAngle(int sweepAngle){
this.sweepAngle = sweepAngle;
postInvalidate();
}
}
代码比较少,主要说一下上面绘制图形的有几个方法,需要解释一下
1. 绘制弧形 :canvas.drawArc(oval, startAngle, sweepAngle, useCenter, paint)
- oval是弧的外接矩形
- startAngle 弧的起始角度,当为0时,这时开始的地方为时钟的三点钟方向
- sweepAngle 为弧所扫过的长度
- useCenter 当为true,弧的末端会与圆心连在一起,本例中设为false,不需要
paint 这个相当重要,默认情况下,画笔的style为fill,也就是绘制出来的图形会填满整个视图,然而我们的效果是要外层圆弧与里圈之间有间隔
所有需要给画笔设置一下风格arcPaint = new Paint(); arcPaint.setStyle(Paint.Style.STROKE); arcPaint.setColor(Color.YELLOW); arcPaint.setStrokeWidth(45);
这样画笔绘制出来的图形就是空心的,设置一下画笔的宽度,就是圆弧的图案了
2. 绘制文字:canvas.drawText(text, start, end, x, y, paint);
常见问题是绘制出来的文字不居中
* start,end 指定从text的哪些内容开始绘制
* x,y为要绘制文字的位置,其中y为上图中的baseline,这个要注意,如果你把y设置为画布的高度中心,会发现文字会偏上,这个方法中y指得是baseLine
baseLine = float baseLine = (circleWidth / 2)
- ((textPaint.descent() + textPaint.ascent()) / 2);
textPaint.setTextAlign(Paint.Align.CENTER);
公式:要绘制控件高度/2 - 字体的(descent+ascent)/2
此方法是stackOverFlow上面找到的最佳答案
3. 控件的大小设置,可以看一下前面的一篇文章:
Demo下载:链接