项目使用,自定义ReplaceSpan,使用富文本方式,定义好协议,显示中文汉字上带拼音功能
public class PYTextSpan extends ReplacementSpan {
// 解析标签
public static final String TAG_PY_TEXT = "span";
// 拼音标签,拼音内容
public static final String TAG_PY_CONTENT = "data-pinyin";
// Span尺寸
private int mSize;
// 拼音内容
private String mPYContent = "";
// 拼音的画笔
private Paint mPYPaint = new Paint();
private Paint mBgPaint = new Paint();
// 拼音和文字的间距
private final int mPyTextPadding = DimenUtils.dp2pxInt(1f);
// 拼音的字体大小
private int mPyFontSize = 0;
private boolean mAddBg;
public PYTextSpan(Attributes attributes) {
initView(attributes);
}
@Override
public int getSize(@NonNull Paint paint,
CharSequence text,
int start,
int end,
Paint.FontMetricsInt fm) {
int textWidth = (int) paint.measureText(text, start, end);
if (mPyFontSize > 0) {
mPYPaint.setTextSize(mPyFontSize);
} else {
// 没有配置拼音字体大小,默认取字大小的2/3
mPYPaint.setTextSize((paint.getTextSize() / 3) * 2);
}
mPYPaint.setColor(paint.getColor());
// 判单当前字符是否为汉字
boolean isChinese = HtmlTextViewUtils.isChinese(text.subSequence(start, end)
.toString()
.trim());
// 汉字默认使用最长的拼音6位,标点符号默认不做处理
int pyWidth = (TextUtils.isEmpty(mPYContent) && !isChinese)
? 0
: (int) mPYPaint.measureText("zhuang");
// 考虑后续可能会设置拼音字体大小,所以取最大
mSize = Math.max(textWidth, pyWidth);
if (fm != null) {
Paint.FontMetricsInt pyFontMetrics = mPYPaint.getFontMetricsInt();
int pyHeight = pyFontMetrics.descent - pyFontMetrics.ascent;
// 加了文字,所以测量时要加上文字的高度
fm.bottom += (pyHeight + mPyTextPadding);
fm.descent += (pyHeight + mPyTextPadding);
}
return mSize;
}
@Override
public void draw(@NonNull Canvas canvas,
CharSequence text,
int start,
int end,
float x,
int top,
int y,
int bottom,
Paint paint) {
drawPYText(canvas, text, start, end, x, y, top, bottom, paint);
}
private void drawPYText(Canvas canvas,
CharSequence rawText,
int start,
int end,
float x,
int y,
int top,
int bottom,
Paint paint) {
// 行高
int lineHeight = bottom - top;
paint.setAntiAlias(true);
//居中
mPYPaint.setTextAlign(Paint.Align.CENTER);
paint.setTextAlign(Paint.Align.CENTER);
Paint.FontMetricsInt textFontMetrics = paint.getFontMetricsInt();
Paint.FontMetricsInt pyFontMetrics = mPYPaint.getFontMetricsInt();
int textHeight = textFontMetrics.descent - textFontMetrics.ascent;
int pyHeight = pyFontMetrics.descent - pyFontMetrics.ascent;
// 因为设置了居中,所以XY都要对应加1/2
int pyStartY = top + (lineHeight - textHeight - pyHeight) / 2 + pyHeight / 2 + mPyTextPadding * 2;
int textStartY = pyStartY + pyHeight + mPyTextPadding + (textHeight - pyHeight) / 2;
final String currentText = rawText.subSequence(start, end).toString();
float startX = x + (mSize / 2);
// 绘制拼音及文字
canvas.drawText(mPYContent, startX, pyStartY, mPYPaint);
// 题干中也有可能含有字母a,这里判断如果是就替换字体
if (currentText.equals("a")
|| currentText.equals("ā")
|| currentText.equals("á")
|| currentText.equals("ǎ")
|| currentText.equals("à")) {
paint.setTypeface(Typeface.createFromAsset(GlobalApplicationProvider.INSTANCE.getApplicationContext()
.getAssets(), "fonts/cn_py.ttf"));
// 新字体库比原生字体大小更大,有可能会被裁剪一些,所以减一点字体大小
paint.setTextSize(paint.getTextSize() - 3);
}
canvas.drawText(currentText, startX, textStartY, paint);
if (mAddBg) {
mBgPaint.setColor(Color.parseColor("#3DFCD043"));
canvas.drawRect(startX - (mSize / 2), pyStartY, startX + (mSize / 2) + 1, pyStartY + textHeight, mBgPaint);
}
}
private void initView(Attributes attrs) {
mPYContent = getPYContent(attrs);
mPYPaint.setAntiAlias(true);
mPYPaint.setTypeface(Typeface.createFromAsset(GlobalApplicationProvider.INSTANCE.getApplicationContext()
.getAssets(), "fonts/cn_py.ttf"));
}
/**
* 设置拼音字体大小
*/
public void setPyTextSize(int fontSize) {
mPyFontSize = fontSize;
}
/**
* 获取拼音内容
*/
private String getPYContent(Attributes attributes) {
if (attributes == null) {
return "";
}
String pyContent = attributes.getValue(TAG_PY_CONTENT);
return TextUtils.isEmpty(pyContent) ? "" : pyContent;
}
public void setBg(boolean addBg) {
this.mAddBg = addBg;
}
public boolean getAddBg() {
return mAddBg;
}
}