应用我的自定义 QuoteSpan 时遇到一个奇怪的问题。它包括此结束标记之后的所有文本:</quote>
. 但是当我尝试替换<quote>...</quote>
成<blockquote>...</blockquote>
以跳过我的自定义 HtmlTagHandler并使用 Android 的 QuoteSpan 的默认实现时,它会起作用。请参阅下面的屏幕截图:
预期结果(使用默认 QuoteSpan):http: //i.stack.imgur.com/bADnU.png
当前输出(使用我的自定义 QuoteSpan):http: //i.stack.imgur.com/VFpkz.png
自定义 HtmlTagHandler - 用于未处理的 html 标签(用于quote
标签)
package com.demoparser.http.parser;
import android.graphics.Typeface;
import android.text.Editable;
import android.text.Html;
import android.text.Spannable;
import android.text.Spanned;
import android.text.style.RelativeSizeSpan;
import android.text.style.StrikethroughSpan;
import android.text.style.StyleSpan;
import android.text.style.TypefaceSpan;
import com.demoparser.util.CustomQuoteSpan;
import org.xml.sax.XMLReader;
public class HtmlTagHandler implements Html.TagHandler {
private static final float[] HEADER_SIZES = {
1.5f, 1.4f, 1.3f, 1.2f, 1.1f, 1f,
};
@Override
public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
if (tag.equalsIgnoreCase("del")) {
if (opening) {
start(output, new Strikethrough());
} else {
end(output, Strikethrough.class, new StrikethroughSpan());
}
} else if (tag.equalsIgnoreCase("pre")) {
if (opening) {
start(output, new Monospace());
} else {
end(output, Monospace.class, new TypefaceSpan("monospace"));
}
} else if (tag.equalsIgnoreCase("quote")) {
if (opening) {
handleP(output);
start(output, new BlockQuote());
} else {
handleP(output);
end(output, BlockQuote.class, new CustomQuoteSpan());
}
}
}
private static void handleP(Editable 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");
}
}
private static Object getLast(Spanned text, Class kind) {
/*
* This knows that the last returned object from getSpans()
* will be the most recently added.
*/
Object[] objs = text.getSpans(0, text.length(), kind);
if (objs.length == 0) {
return null;
} else {
return objs[objs.length - 1];
}
}
private static void start(Editable text, Object mark) {
int len = text.length();
text.setSpan(mark, len, len, Spannable.SPAN_MARK_MARK);
}
private static void end(Editable text, Class kind, Object repl) {
int len = text.length();
Object obj = getLast(text, kind);
int where = text.getSpanStart(obj);
text.removeSpan(obj);
if (where != len) {
text.setSpan(repl, where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
public static class Strikethrough {}
public static class Monospace {}
public static class BlockQuote {}
}
自定义报价跨度
package com.demoparser.util;
/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import android.graphics.Canvas;
import android.graphics.Paint;
import android.text.Layout;
import android.text.style.LeadingMarginSpan;
import android.text.style.LineBackgroundSpan;
public class CustomQuoteSpan implements LeadingMarginSpan, LineBackgroundSpan {
private static final int STRIPE_WIDTH = 5;
private static final int GAP_WIDTH = 8;
private final int mBackgroundColor;
private final int mColor;
public QuoteSpan() {
super();
mBackgroundColor = 0xffddf1fd;
mColor = 0xff098fdf;
}
public int getLeadingMargin(boolean first) {
return STRIPE_WIDTH + GAP_WIDTH;
}
public void drawLeadingMargin(Canvas c, Paint p, int x, int dir,
int top, int baseline, int bottom,
CharSequence text, int start, int end,
boolean first, Layout layout) {
Paint.Style style = p.getStyle();
int color = p.getColor();
p.setStyle(Paint.Style.FILL);
p.setColor(mColor);
c.drawRect(x, top, x + dir * STRIPE_WIDTH, bottom, p);
p.setStyle(style);
p.setColor(color);
}
@Override
public void drawBackground(Canvas c, Paint p, int left, int right, int top, int baseline, int bottom, CharSequence text, int start, int end, int lnum) {
int paintColor = p.getColor();
p.setColor(mBackgroundColor);
c.drawRect(left, top, right, bottom, p);
p.setColor(paintColor);
}
}
以及我尝试应用自定义 QuoteSpan 的 HTML 元素:
<quote>
<div class="q_b">
<div class="q_tl">
<div class="q_tr">
<div class="q_bl">
<div class="q_br">
<div class="q_body">
<b class="qfont">Quote:</b>
<div style="padding:5px;">
<div class="q_by">
Originally Posted by
<strong>: <a href="/index.php?thread=1#msg2"> username on 1-1-2016 00:00 AM</a></strong>
</div>
Sample Quoted Text 1
<br>
<br>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</quote>
<br>
<br>
This message should not be inside the QuoteSpan
我Html.fromHtml(...)
用来渲染跨度。
Html.fromHtml(message, null, new HtmlTagHandler())
这是开始和结束标签索引的日志:
START: 0
END: 138 <-- should be 87
任何人有任何想法来实现与默认 QuoteSpan 的输出相同的结果或指出错误的实现?先感谢您。