Android学习笔记-自定义视图之比例图

前一段时间看一个学习效率的问题,发现自己的学习效率的确不高,写博客主要是为了加深映像,然后的在写的时候希望能够进一步能够理解。给大家看一张图

这里写图片描述

图片里面有一项:教授给他人 学习内容的留存率最大为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. 控件的大小设置,可以看一下前面的一篇文章:

自定义view的属性

Demo下载:链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值