我有一个应用程序,可以分页显示大量文本,并为每个单词或句子设置多个span。我正在使用ReplacementSpan来绘制每个单词的背景。我不能使用BackgroundSpan,因为它太简单了,无法控制画布。由于ReplacementSpan扩展了MetricAffectingSpan,这会影响文本的布局,从而完全破坏我的分页。我正在使用StaticLayout来计算每个页面的文本,但StaticLayout不允许跨度,因此它可以预先计算跨度大小的影响。
是否有替代ReplacementSpan的方法?如何在不影响文本本身的大小和布局的情况下绘制所需的背景?
以下是我的ReplacementSpan代码:
是否有替代ReplacementSpan的方法?如何在不影响文本本身的大小和布局的情况下绘制所需的背景?
以下是我的ReplacementSpan代码:
public class BackgroundColorWithoutLineHeightSpan extends ReplacementSpan {
private static final float DP_ACTIVE = ViewsUtils.dpToPx(4);
private static final int DP_OUTSIDE_PADDING = (int) ViewsUtils.dpToPx(6);
private static final float DP_PHRASE = ViewsUtils.dpToPx(4);
private static final float DP_ROUNDED = ViewsUtils.dpToPx(3);
private final int mColor;
private final int mTextHeight;
private int mBorderColor;
private boolean mIsSelected;
private boolean mIsPhrase;
public BackgroundColorWithoutLineHeightSpan(int color, int textHeight, boolean isPhrase) {
mColor = color;
mTextHeight = textHeight;
mIsPhrase = isPhrase;
}
public BackgroundColorWithoutLineHeightSpan(int color, int textHeight, boolean isSelected, int borderColor, boolean isPhrase) {
mColor = color;
mTextHeight = textHeight;
mIsSelected = isSelected;
mBorderColor = borderColor;
mIsPhrase = isPhrase;
}
@Override
public int getSize(@NonNull Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
return Math.round(measureText(paint, text, start, end));
}
@Override
public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
canvas.save();
Rect newRect = canvas.getClipBounds();
newRect.inset(-DP_OUTSIDE_PADDING, -DP_OUTSIDE_PADDING);
canvas.clipRect(newRect, Region.Op.REPLACE);
float measuredText = measureText(paint, text, start, end);
int paintColor = paint.getColor();
if (!mIsSelected) {
RectF rect;
rect = new RectF(x, top, x + measuredText, top + mTextHeight);
paint.setStrokeWidth(0.0f);
paint.setColor(mColor);
paint.setStyle(Paint.Style.FILL);
canvas.drawRoundRect(rect, DP_ROUNDED, DP_ROUNDED, paint);
} else {
RectF rect;
if (mIsPhrase) {
rect = new RectF(x - DP_PHRASE, top - DP_PHRASE, x + measuredText + DP_PHRASE, top + mTextHeight + DP_PHRASE);
} else {
rect = new RectF(x - DP_ACTIVE, top - DP_ACTIVE, x + measuredText + DP_ACTIVE, top + mTextHeight + DP_ACTIVE);
}
paint.setStrokeWidth(0.0f);
paint.setColor(mColor);
paint.setStyle(Paint.Style.FILL);
canvas.drawRoundRect(rect, DP_ROUNDED, DP_ROUNDED, paint);
RectF border;
if (mIsPhrase) {
border = new RectF(x - DP_PHRASE, top - DP_PHRASE, x + measuredText + DP_PHRASE, top + mTextHeight + DP_PHRASE);
} else {
border = new RectF(x - DP_ACTIVE, top - DP_ACTIVE, x + measuredText + DP_ACTIVE, top + mTextHeight + DP_ACTIVE);
}
paint.setColor(mBorderColor);
paint.setStrokeWidth(4.0f);
paint.setStyle(Paint.Style.STROKE);
canvas.drawRoundRect(border, DP_ROUNDED, DP_ROUNDED, paint);
}
paint.setStyle(Paint.Style.FILL);
paint.setColor(paintColor);
canvas.drawText(text, start, end, x, y, paint);
canvas.restore();
}
private float measureText(Paint paint, CharSequence text, int start, int end) {
return paint.measureText(text, start, end);
}
}
Layout#getSelectionPath
,检查一下,也许有帮助。 - pskink