1. 效果展示:
我们在 “
Wheel ProgressBar 实现之一——画一条弧” 中阐述了如何在一个矩形区域内精确画弧。本节我们实现以圆环中心(即矩形区域中心)为对称点画进度文本,如下图的效果所示:
2. 实现原理:
在 android 中画字符是通过 Canvas.drawText(String text, float x, float y, Paint paint); 这个接口来实现的,除了设定画笔参数以外,我们最重要的是确定 x 和 y 的值。默认情况下,(x, y) 指的是该字符相对于其所在区域内的左下坐标点,其中,x 为字符左边缘与所在区域左边缘的距离,y 为字符基线与所在区域底部之间的距离,网上很多说法转载同一篇博文说 x 是字符左边在屏幕的位置,这个解释很模糊,经验证在 View 内部绘图时是错误的。
具体到本文的展示效果,我们通过如下的示意图来解释一下具体的实现原理:
如图所示,我们要先明确四个区域:字符 ‘90’,字符 ‘%’,两个字符之间的间隔,所在的正方形区域。
各个区域的 size 在图中已经描述出来,我们的任务是要计算出两个字符的左下坐标点,即 (Xn, Yn) 和 (Xp, Yp)。
根据图中的描述,我们可以很轻易的通过如下公式计算出这两个坐标:
字符及其间隔的宽度的一半:offset = (Wn + Wp + Dh) / 2
Xn = W/2 - offset
Yn = W/2 + Hn/2
Xp = W/2 + offset - Wp
Yp = W/2 - Hn/2 + Hp
其中,Wn, Hn, Wp, Hp 都可通过相关接口提供,Dh 可由用户指定
3. 具体实现:
我们继续在 “Wheel ProgressBar 实现之一——画一条弧” 中定义的 CustomArc 类中叠加实现此功能:
1、在 onAttachedToWindow() 方法中设置绘字符的画笔参数:
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
public void onAttachedToWindow() {
super.onAttachedToWindow();
... ...
mProgressPaint.setColor(Color.BLACK);
mProgressPaint.setAntiAlias(true);
mProgressPaint.setTextSize(180);
mProgressPaint.setTypeface(Typeface.DEFAULT_BOLD);
mPercentPaint.setColor(Color.BLACK);
mPercentPaint.setStyle(Style.FILL);
mPercentPaint.setAntiAlias(true);
mPercentPaint.setTextSize((int)(180 * 0.7));
mPercentPaint.setTypeface(Typeface.DEFAULT_BOLD);
invalidate();
mProgressPaint.setTypeface(Typeface.DEFAULT_BOLD);
mPercentPaint.setColor(Color.BLACK);
mPercentPaint.setStyle(Style.FILL);
mPercentPaint.setAntiAlias(true);
mPercentPaint.setTextSize((int)(180 * 0.7));
mPercentPaint.setTypeface(Typeface.DEFAULT_BOLD);
invalidate();
}
2、在
onDraw() 方法中画字符:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
... ...
mProgressPaint.getTextBounds("90", 0, "90".length(), mProgBounds);
mPercentPaint.getTextBounds("%", 0, 1, mPercentBounds);
float offset =
(mProgBounds.width() + mPercentBounds.width() + mPercentBounds.width() / 2) / 2;
(mProgBounds.width() + mPercentBounds.width() + mPercentBounds.width() / 2) / 2;
canvas.drawText("90",
this.getWidth() / 2 - offset,
this.getHeight() / 2 + mProgBounds.height() / 2,
mProgressPaint);
canvas.drawText("%",
this.getWidth() / 2 - offset,
this.getHeight() / 2 + mProgBounds.height() / 2,
mProgressPaint);
canvas.drawText("%",
this.getWidth() / 2 + offset - mPercentBounds.width(),
this.getHeight() / 2 - mProgBounds.height() / 2 + mPercentBounds.height(),
mPercentPaint);
this.getHeight() / 2 - mProgBounds.height() / 2 + mPercentBounds.height(),
mPercentPaint);
}
3、完整的工程请下载:CustomArc