最近在做一些图片与文字合成的研究,一些背景比较复杂的图片与文字合成后出现颜色冲突或者融合的情况,合成效果比较差。经研究,我们决定使用描边来解决这个问题。

Android TextView本身并没有直接的API来设置这个效果,一开始经过查找,发现有些朋友使用shadow相关的属性来实现。shadow,即是阴影,即出现在文字下方某指定偏移位置的一块模糊的带颜色的区域。代码如下:

1
2
3
4
android:shadowColor="@color/xxx"
android:shadowDx="@dimen/xxx"
android:shadowDy="@dimen/xxx"
android:shadowRadias="@dimem/xxx"

然而shadow的效果并不是很好,给人一种虚化以及不干净的感觉。我们决定采用真正的描边来做。注意到Paint类有一个设置画笔绘制样式的API:setStyle();我们决定从这里入手。经过一番验证,得到如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class StrokeTextView extends TextView {
private final int strokeColor;
private final float strokeWidth;
TextPaint paint = new TextPaint();

public StrokeTextView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.StrokeStyleable, 0, 0);
strokeWidth = a.getDimension(R.styleable.StrokeStyleable_strokeWidthMe, 6);
strokeColor = a.getColor(R.styleable.StrokeStyleable_strokeColorMe, Color.WHITE);
}

@Override
protected void onDraw(Canvas canvas) {
final ColorStateList textColor = getTextColors();
paint = this.getPaint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeMiter(10);
this.setTextColor(strokeColor);
paint.setStrokeWidth(strokeWidth);
super.onDraw(canvas);
paint.setStyle(Paint.Style.FILL);
setTextColor(textColor);
super.onDraw(canvas);
}
}

如上面代码所示,实现原理为先设置画笔样式为Stroke,绘制一次,然后再设置样式为Fill,再绘制一次,就得到了真正的描边效果。有问题请在下面评论区告诉我