我知道如何在静态文本中的部分文本上设置多个跨度,因为我已经问过here:
final SpannableString text = new SpannableString("Hello stackOverflow");
text.setSpan(new RelativeSizeSpan(1.5f), text.length() - "stackOverflow".length(), text.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
text.setSpan(new ForegroundColorSpan(Color.RED), 3, text.length() - 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
tv.setText(text);
这会将“stackOverflow”设置为自身有2个跨度。
我也知道如何在文本的一部分上设置可绘制的跨度,因为我已经问过here。
现在我需要在通过使用占位符格式化文本生成的文本上设置2个跨度,同时仍然像往常一样设置其他样式。
例如,假设我在strings.xml中有下一个文本:
<string name="potential_free_upgrade_1_d_months">
<![CDATA[
Potential free upgrade: <uu><b><font color=\'#3792e5\'>%1$d months</font></b></uu>]]>
</string>
计划是“%1 $ d个月”的文字颜色为“#3792e5”,并且会有一个比默认颜色略低的特殊下划线。我使用特殊的自定义标签“uu”作为特殊下划线,用代码处理。
事情是,无论我做什么,我都找不到如何同时显示文字颜色和下划线。
由于此问题有一个占位符(并且文本可能在要格式化的文本周围不同),我不得不使用“Html.FromHtml”:
String formattedStr = getString(R.string.potential_free_upgrade_1_d_months, 9);
Spanned textToShow = Html.fromHtml(formattedStr, null, new TagHandler() {
int start;
@Override
public void handleTag(final boolean opening, final String tag, Editable output, final XMLReader xmlReader) {
switch (tag) {
case "uu":
if (opening)
start = output.length();
else {
int end = output.length();
//output.setSpan(new ForegroundColorSpan(0xff3792e5), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
output.setSpan(
new DrawableSpan(ResourcesCompat.getDrawable(getResources(), R.drawable.bit_below_underline, null)),
start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
});
titleTextView.setText(textToShow);
DrawableSpan.java
public class DrawableSpan extends ReplacementSpan {
private Drawable mDrawable;
private final Rect mPadding;
public DrawableSpan(Drawable drawable) {
super();
mDrawable = drawable;
mPadding = new Rect();
mDrawable.getPadding(mPadding);
}
@Override
public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, @NonNull Paint paint) {
RectF rect = new RectF(x, top, x + measureText(paint, text, start, end), bottom);
mDrawable.setBounds((int) rect.left - mPadding.left, (int) rect.top - mPadding.top, (int) rect.right + mPadding.right, (int) rect.bottom + mPadding.bottom);
canvas.drawText(text, start, end, x, y, paint);
mDrawable.draw(canvas);
}
@Override
public int getSize(@NonNull Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
return Math.round(paint.measureText(text, start, end));
}
private float measureText(Paint paint, CharSequence text, int start, int end) {
return paint.measureText(text, start, end);
}
}
RES /抽拉/ bit_below_underline.xml
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="line">
<padding android:bottom="30dp"/>
<stroke
android:width="1dp"
android:color="#3792e5"/>
</shape>
我试图将2“setSpan”一起调用(首先在上面的代码中注释),但它没有帮助。
如何在文本部分设置2个跨度,如上所述(带占位符的部分文本),以便一个是文本颜色,另一个是自定义下划线?
答案 0 :(得分:0)
在测试代码时,似乎div
在任何ReplacementSpans
之前被绘制。因此,请尝试使用CharacterStyleSpan
。它将在MetricAffectingSpan
之前绘制。
因此,请使用自定义ReplacementSpans
代替MetricAffectingSpan
ForegroundColorSpan
好的。我试图从android SDK源代码解释这个问题,在这个for循环中有import android.text.TextPaint;
import android.text.style.MetricAffectingSpan;
public class BGColorSpan extends MetricAffectingSpan {
private int color;
public BGColorSpan(int color) {
this.color = color;
}
@Override
public void updateMeasureState(TextPaint textPaint) {
textPaint.setColor(color);
}
@Override
public void updateDrawState(TextPaint textPaint) {
textPaint.setColor(color);
}
}
个关键字,它将跳过continue
的呈现
CharacterStyleSpan