@Andro Selva 的解释是正确的,对此没有什么可做的。令人沮丧的是,API 24 及更高版本在调用中包含标志后情况变得更好
Spanned fromHtml (String source,
int flags,
Html.ImageGetter imageGetter,
Html.TagHandler tagHandler);
我怀疑FROM_HTML_SEPARATOR_LINE_BREAK_PARAGRAPH标志会将标准段落终止的双“\n\n”减少到换行符的单个“\n”
鉴于 Android 版本的历史 ~ 我负担不起专门为 Android API 24+ 编写软件!所以...我找到了一个包含 2 个额外自定义标签的 kludge 解决方案。
1. <scale factor="x.xx">... </scale>
2. <default>... </default>
都通过这个方法调用RelativeSizeSpan类
private void ProcessRelativeSizeTag(float scalefactor, boolean opening, Editable output) {
int len = output.length();
if (opening) {
System.out.println("scalefactor open: " + scalefactor);
output.setSpan(new RelativeSizeSpan(scalefactor), len, len,
Spannable.SPAN_MARK_MARK);
} else {
Object obj = getLast(output, RelativeSizeSpan.class);
int where = output.getSpanStart(obj);
scalefactor = ((RelativeSizeSpan)obj).getSizeChange();
output.removeSpan(obj);
System.out.println("scalefactor close: " + scalefactor);
if (where != len) {
output.setSpan(new RelativeSizeSpan(scalefactor), where, len,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
从提供给Html.fromHtml
方法的自定义 TagHandler 调用,即:
private static class CustomTagHandler implements Html.TagHandler {
private void ProcessRelativeSizeTag(float scalefactor, boolean opening, Editable output) {
int len = output.length();
if (opening) {
//mSizeStack.push(scalefactor);
System.out.println("scalefactor open: " + scalefactor);
output.setSpan(new RelativeSizeSpan(scalefactor), len, len,
Spannable.SPAN_MARK_MARK);
} else {
Object obj = getLast(output, RelativeSizeSpan.class);
int where = output.getSpanStart(obj);
scalefactor = ((RelativeSizeSpan)obj).getSizeChange();
output.removeSpan(obj);
//scalefactor = (float)mSizeStack.pop();
System.out.println("scalefactor close: " + scalefactor);
if (where != len) {
output.setSpan(new RelativeSizeSpan(scalefactor), where, len,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
...
final HashMap<String, String> mAttributes = new HashMap<>();
@Override
public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
String Attr;
processAttributes(xmlReader);
if ("default".equalsIgnoreCase(tag)) {
ProcessRelativeSizeTag(mDefaultTextSize, opening, output);
return;
}
if ("scale".equalsIgnoreCase(tag)) {
Attr = mAttributes.get("factor");
if (Attr != null && !Attr.isEmpty()) {
float factor = parseFloat(Attr);
if (factor > 0)
ProcessRelativeSizeTag(factor, opening, output);
}
return;
...
}
}
要使用,我将Textview
对象的文本大小设置为1。即1像素!然后我在变量中设置所需的真实文本大小mDefaultTextSize
。我在一个htmlTextView
扩展TextView
为:
public class htmlTextView extends AppCompatTextView {
static Typeface mLogo;
static Typeface mGAMZ;
static Typeface mBrush;
static Typeface mStandard;
int GS_PAINTFLAGS = FILTER_BITMAP_FLAG | ANTI_ALIAS_FLAG | SUBPIXEL_TEXT_FLAG | HINTING_ON;
static float mDefaultTextSize;
static Typeface mDefaultTypeface;
etc
}
其中包括公共方法
public void setDefaultTextMetrics(String face, float defaultTextSize) {
mDefaultTypeface = mStandard;
if (face != null) {
if ("gamz".equalsIgnoreCase(face)) {
mDefaultTypeface = mGAMZ;
} else {
if ("brush".equalsIgnoreCase(face)) {
mDefaultTypeface = mBrush;
}
}
}
setTypeface(mDefaultTypeface);
setTextSize(1);
mDefaultTextSize = defaultTextSize;
}
一个简单的((htmlTextView)tv).setDefaultTextMetrics(null, 30);
调用设置我htmlTextView
使用我的标准字体作为默认字体,文本大小为 30。
然后当我给它这个例子以在 fromHtml 中使用时:
<string name="htmlqwert">
<![CDATA[
<p><default><scale factor="1.5"><box> qwertQWERT </box></scale></default></p>
<p><default><scale factor="1.5"><box> qwertQWERT </box></scale></default></p>
<p><default><scale factor="1.5"><box> qwertQWERT </box></scale></default></p>
<p><default><scale factor="1.5"><box> qwertQWERT </box></scale></default></p>
]]>
</string>
我的自定义标签<box>
只是让我突出显示文本的背景。请参见附图,其中显示了一个使用<default>
标签的结果,其中TextView
文本大小设置为 1,<default>
标签调用 aRelevantSizeSpan
的因子为 30,其中一个具有:
<string name="htmlqwert">
<![CDATA[
<p><scale factor="1.5"><box> qwertQWERT </box></scale></p>
<p><scale factor="1.5"><box>qwertQWERT</box></scale></p>
<p><scale factor="1.5"><box>qwertQWERT</box></scale></p>
<p><scale factor="1.5"><box>qwertQWERT</box></scale></p>
]]>
</string>
不使用<default>
标签,而是将TextView
文本大小设置为 30。在第一种情况下,额外的新行仍然存在,但它只有 1 个像素高!
<scale factor="1.5">...</scale>
注意标签没有真正的意义。它们只是从其他测试中遗留下来的人工制品。
结果:下面的两个示例在段落之间都有 2 个换行符,但在左侧的那个中,其中一个行只有 1 个像素高。我将留给读者弄清楚如何将其减少到零,但不要使用 0 的文本大小