我们都知道 Android 中使用 Spannable 可以实现 TextView 富文本的显示,但是在自定义控件中如何使用 Spannable 绘制不同样式的文字呢?
例如这种效果,标题中的 分数字61
是粗体,分
是常规字体,并且相对于 61
更小些。
第一反应可能是使用 SpannableString.setSpan()
设置 RelativeSizeSpan
, 然后在 onDraw()
中进行绘制,事实是这样实现是没有效果的,因为 onDraw()
中只能获取到 SpannableString
中的内容,拿不到 Span
.
那如何在自定义View 中使用 Spannable 呢? 答案就是系统提供的 Layout
类,
/**
* A base class that manages text layout in visual elements on
* the screen.
* <p>For text that will be edited, use a {@link DynamicLayout},
* which will be updated as the text changes.
* For text that will not change, use a {@link StaticLayout}.
*/
public abstract class Layout {
}
可以看到 Layout
是一个抽象类,有三个子类,可以实现一些自动换行的显示效果。
- BoringLayout
- DynamicLayout
- StaticLayout
实现代码
1. 定义自定义属性
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ArcProgressView">
<attr name="arcBackgroundColor" format="color" />
<attr name="arcProgressColor" format="color" />
<attr name="arcSubTitleColor" format="color" />
<attr name="arcStrokeWidth" format="dimension" />
<attr name="arcTitleTextSize" format="dimension" />
<attr name="arcSubTitleTextSize" format="dimension" />
<attr name="arcProgress" format="float" />
<attr name="arcTitleNumber" format="integer" />
</declare-styleable>
</resources>
2. 继承 View, 在 onDraw()
中绘制
public class ArcProgressView extends View {
private int arcBackgroundColor; // 圆弧背景颜色
private int arcProgressColor; // 圆弧进度颜色
private int arcSubTitleColor; // 副标题颜色
private float arcStrokeWidth; // 圆弧线的厚度
private float arcTitleTextSize; // 标题文字大小
private float arcSubTitleTextSize; // 副标题文字大小
private float arcProgress; // 进度
private int arcTitleNumber; // 值
private Paint paint;
private float centerX;
private float centerY;
private float radius; // 半径
private RectF rectF;
private int startAngle = 135;
private int sweepAngle = 270;
private String subTitle