找到解决方案:
fromHtml 返回类型为 Spanned。因此,我将返回值分配给一个变量,将其转换为字符串,然后使用.trim()方法。
这会删除末尾的所有空格。
是的,你想到的是正确的。它会在底部添加空格。但在此之前,让我解释一下它是如何工作的。
你需要查看HTML类来了解它是如何工作的。
简单来说,它是这样工作的:每当你的Html
类查看一个<p>
标签时,它只是简单地将两个"\n"字符附加到末尾。
在这种情况下,你在底部看到的空白实际上是由于两个\n被附加到段落末尾。
我已经添加了Html类的实际方法,负责执行此操作。
private static void handleP(SpannableStringBuilder text) {
int len = text.length();
if (len >= 1 && text.charAt(len - 1) == '\n') {
if (len >= 2 && text.charAt(len - 2) == '\n') {
return;
}
text.append("\n");
return;
}
if (len != 0) {
text.append("\n\n");
}
}
/n
。然而,我找到了自己的解决方案,将在下面写出答案。 - wh-dev<a>
标签而不是 <p>
,<p>
会在末尾添加回车符,但是 a
不会,如果你使用 <b>
,需要自己记得写上 \n
,并且样式会保留。@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个额外自定义标签的权宜之计解决方案。
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);
}
}
}
这是从自定义的TagHandler中调用的,该TagHandler被提供给Html.fromHtml
方法,即:
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
。 我把所有的Html功能放在一个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。<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>
标签通过30倍因子调用了RelevantSizeSpan
,另一个结果如下:
<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像素高!
NB:没有真正的必要使用<scale factor="1.5">...</scale>
标签。它们只是其他测试留下的剩余物。
结果:以下两个示例在段落之间都有2个换行符,但在左侧的示例中,其中一行只有1像素高。我将让读者自己想办法将其减少到零,但不要使用0的文本大小。
这个解决方案对我很有效。 创建一个帮助方法来替换所有段落的起始和结束标签,并将它们全部替换为空字符。
@Nullable
public static String removeParagraphTags(@Nullable String input) {
if (input == null) {
return null;
}
return input.replaceAll("<p>", "").replaceAll("</p>", "");
}
使用方法
String input = "<p>This is some text in a paragraph.</p>";
HtmlCompat.fromHtml(StringUtils.removeParagraphTags(input),HtmlCompat.FROM_HTML_MODE_COMPACT)