Android 中TextView文字描边实现(一)
Android 9.0效果图:
Android 10.0效果图:
据以上两图显示此方法只用于android9.0可行,第二种方法见Android中TextView文字描边实现(二)
1.attrs.xml文件
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- 自定义控件的名称 -->
<declare-styleable name="StrokeTextView">
<!-- 自定义的属性名称 和对应的单位 -->
<attr name="outerColor" format="color|reference" />
<attr name="innnerColor" format="color|reference" />
</resources>
2.StrokeTextView的实现
package com.app.animalchess.widget;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.widget.TextView;
import com.app.animalchess.R;
import java.lang.reflect.Field;
/**
* @Author : XiaoXred
* @Time : On 2020/10/22 15:59
* @Description : StrokeTextView 文字内容有描边的TextView
*/
public class StrokeTextViewextends TextView {
TextPaintm_TextPaint;
int mInnerColor;
int mOuterColor;
public StrokeTextView(Context context,int outerColor,int innnerColor) {
super(context);
m_TextPaint =this.getPaint();
this.mInnerColor = innnerColor;
this.mOuterColor = outerColor;
// TODO Auto-generated constructor stub
}
public StrokeTextView(Context context, AttributeSet attrs) {
super(context, attrs);
m_TextPaint =this.getPaint();
//获取自定义的XML属性名称
TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.StrokeTextView);
//获取对应的属性值
this.mInnerColor = a.getColor(R.styleable.StrokeTextView_innnerColor,0xffffff);
this.mOuterColor = a.getColor(R.styleable.StrokeTextView_outerColor,0xffffff);
}
public StrokeTextView(Context context, AttributeSet attrs, int defStyle,int outerColor,int innnerColor) {
super(context, attrs, defStyle);
m_TextPaint =this.getPaint();
this.mInnerColor = innnerColor;
this.mOuterColor = outerColor;
// TODO Auto-generated constructor stub
}
private boolean m_bDrawSideLine =true; // 默认采用描边
/**
*
*/
@Override
protected void onDraw(Canvas canvas) {
if (m_bDrawSideLine) {
// 描外层
// super.setTextColor(Color.BLUE); // 不能直接这么设,如此会导致递归
// setTextColorUseReflection(Color.YELLOW);
setTextColorUseReflection(getResources().getColor(R.color.color_CC7B02));
m_TextPaint.setStrokeWidth(10); // 描边宽度
m_TextPaint.setStyle(Paint.Style.FILL_AND_STROKE); // 描边种类
m_TextPaint.setFakeBoldText(true); // 外层text采用粗体
//radius:阴影半径 dx:X轴方向的偏移量 dy:Y轴方向的偏移量 color:阴影颜色
m_TextPaint.setShadowLayer(5, 0,0,0); // 字体的阴影效果,可以忽略
super.onDraw(canvas);
// 描内层,恢复原先的画笔
// super.setTextColor(Color.BLUE); // 不能直接这么设,如此会导致递归
setTextColorUseReflection(Color.WHITE);
m_TextPaint.setStrokeWidth(0);
// m_TextPaint.setStyle(Style.FILL_AND_STROKE);
m_TextPaint.setFakeBoldText(false);
m_TextPaint.setShadowLayer(0, 0, 0, 0);
}
super.onDraw(canvas);
}
/**
* 使用反射的方法进行字体颜色的设置
* @param color
*/
private void setTextColorUseReflection(int color) {
Field textColorField;
try {
textColorField = TextView.class.getDeclaredField("mCurTextColor");
textColorField.setAccessible(true);
textColorField.set(this, color);
textColorField.setAccessible(false);
}catch (NoSuchFieldException e) {
e.printStackTrace();
}catch (IllegalArgumentException e) {
e.printStackTrace();
}catch (IllegalAccessException e) {
e.printStackTrace();
}
m_TextPaint.setColor(color);
}
}
3.布局文件中StrokeTextView的使用
<com.app.animalchess.widget.StrokeTextView
android:layout_width="260dp"
android:layout_height="50dp"
android:text="登录"
android:background="@drawable/login_btn_wchat_nor"
android:textSize="18sp"
android:gravity="center"
android:layout_marginTop="140dp"
android:layout_gravity="center"
app:outerColor="@color/color_CC7B02"
app:innnerColor="@color/color_ffffff" />