我编写了一个类来执行带有轮廓的文本,并且仍然支持所有其他属性和普通文本视图的绘制。
它基本上使用TextView上的super.onDraw(Canves canvas),但使用不同的样式绘制了两次。
希望这会有所帮助。
public class TextViewOutline extends TextView {
// constants
private static final int DEFAULT_OUTLINE_SIZE = 0;
private static final int DEFAULT_OUTLINE_COLOR = Color.TRANSPARENT;
// data
private int mOutlineSize;
private int mOutlineColor;
private int mTextColor;
private float mShadowRadius;
private float mShadowDx;
private float mShadowDy;
private int mShadowColor;
public TextViewOutline(Context context) {
this(context, null);
}
public TextViewOutline(Context context, AttributeSet attrs) {
super(context, attrs);
setAttributes(attrs);
}
private void setAttributes(AttributeSet attrs){
// set defaults
mOutlineSize = DEFAULT_OUTLINE_SIZE;
mOutlineColor = DEFAULT_OUTLINE_COLOR;
// text color
mTextColor = getCurrentTextColor();
if(attrs != null) {
TypedArray a = getContext().obtainStyledAttributes(attrs,R.styleable.TextViewOutline);
// outline size
if (a.hasValue(R.styleable.TextViewOutline_outlineSize)) {
mOutlineSize = (int) a.getDimension(R.styleable.TextViewOutline_outlineSize, DEFAULT_OUTLINE_SIZE);
}
// outline color
if (a.hasValue(R.styleable.TextViewOutline_outlineColor)) {
mOutlineColor = a.getColor(R.styleable.TextViewOutline_outlineColor, DEFAULT_OUTLINE_COLOR);
}
// shadow (the reason we take shadow from attributes is because we use API level 15 and only from 16 we have the get methods for the shadow attributes)
if (a.hasValue(R.styleable.TextViewOutline_android_shadowRadius)
|| a.hasValue(R.styleable.TextViewOutline_android_shadowDx)
|| a.hasValue(R.styleable.TextViewOutline_android_shadowDy)
|| a.hasValue(R.styleable.TextViewOutline_android_shadowColor)) {
mShadowRadius = a.getFloat(R.styleable.TextViewOutline_android_shadowRadius, 0);
mShadowDx = a.getFloat(R.styleable.TextViewOutline_android_shadowDx, 0);
mShadowDy = a.getFloat(R.styleable.TextViewOutline_android_shadowDy, 0);
mShadowColor = a.getColor(R.styleable.TextViewOutline_android_shadowColor, Color.TRANSPARENT);
}
a.recycle();
}
PFLog.d("mOutlineSize = " + mOutlineSize);
PFLog.d("mOutlineColor = " + mOutlineColor);
}
private void setPaintToOutline(){
Paint paint = getPaint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(mOutlineSize);
super.setTextColor(mOutlineColor);
super.setShadowLayer(mShadowRadius, mShadowDx, mShadowDy, mShadowColor);
}
private void setPaintToRegular() {
Paint paint = getPaint();
paint.setStyle(Paint.Style.FILL);
paint.setStrokeWidth(0);
super.setTextColor(mTextColor);
super.setShadowLayer(0, 0, 0, Color.TRANSPARENT);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setPaintToOutline();
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
public void setTextColor(int color) {
super.setTextColor(color);
mTextColor = color;
}
@Override
public void setShadowLayer(float radius, float dx, float dy, int color) {
super.setShadowLayer(radius, dx, dy, color);
mShadowRadius = radius;
mShadowDx = dx;
mShadowDy = dy;
mShadowColor = color;
}
public void setOutlineSize(int size){
mOutlineSize = size;
}
public void setOutlineColor(int color){
mOutlineColor = color;
}
@Override
protected void onDraw(Canvas canvas) {
setPaintToOutline();
super.onDraw(canvas);
setPaintToRegular();
super.onDraw(canvas);
}
}
attr.xml
<declare-styleable name="TextViewOutline">
<attr name="outlineSize" format="dimension"/>
<attr name="outlineColor" format="color|reference"/>
<attr name="android:shadowRadius"/>
<attr name="android:shadowDx"/>
<attr name="android:shadowDy"/>
<attr name="android:shadowColor"/>
</declare-styleable>