介绍
前天做了一个带百分比显示的条形进度条,效果如下:
实现
这个自定义进度条, 看起来简单, 做起来。。。其实也很简单: 主要通过继承View类, 并重写其onDraw方法实现。
思路分为3步:
1. 画进图条背景(图中灰色部分
2. 根据进度画出进度条(图中绿色部分
3. 绘制进度百分比(图中白色文本
前面2个步骤非常简单, 通过drawRoundRect方法进行绘制即可, 第3步也不难, 重点在于定位好绘制文本的位置。文本的水平位置很容易确认, 因为Paint对象提供了measureText方法, 可以获得到文本的长度。用绿色进度条的长度和它做一个减法, 就能得出绘制文本的水平坐标。
竖直坐标, 就有些复杂了。先看下图(图片来源:http://www.xyczero.com/blog/article/20/):
在Canvas对象的drawText方法中, y坐标参数指的是baseline线的y坐标参数。我们所要做的, 就是求出, 当文本垂直居中显示时, 该y坐标的值。
求值, 需要用到Paint的内部类:FontMetrics。
public static class FontMetrics {
/**
* The maximum distance above the baseline for the tallest glyph in
* the font at a given text size.
*/
public float top;
/**
* The recommended distance above the baseline for singled spaced text.
*/
public float ascent;
/**
* The recommended distance below the baseline for singled spaced text.
*/
public float descent;
/**
* The maximum distance below the baseline for the lowest glyph in
* the font at a given text size.
*/
public float bottom;
/**
* The recommended additional space to add between lines of text.
*/
public float leading;
}
由源码可以看到该类对象提供的几个值的含义。其中:
ascent 代表的就是上图中ascent线的y坐标减去baseline线的y坐标, 所以该值为负数;
descent 代表的就是上图中的descent线的y坐标减去baseline的y坐标, 所以该值为正数;
由此,可知: 文本的高度为2个距离之和, 即2个数字之差:
height = descent - ascent; (1)
又:设空间高度为Height
baseline y坐标 baseY = 1/2 Height + (1/ 2 height - descent); (2)
由(1) (2)式可得:
baseY = 1/2 Height - 1/2 ascent - 1/2 descent;
由此, 需要的数据都被求出来了。
同时, 在values/attrs.xml中添加自定义参数, 使三种颜色可以在布局文件中被配置:
attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable