奇怪的TagHandler行为检测开关标签

dar*_*ord 4 android textview

我正在尝试使用TextView显示带有自定义标记的String文本:

字符串:

"<articlelink>text1</articlelink> padding<articlelink>text2</articlelink>"
Run Code Online (Sandbox Code Playgroud)

articlelink是自定义标记的位置.我使用自定义的HTML.TagHandler来处理标签:

private class MyTagHandler implements Html.TagHandler {

    private int startIndex = 0;
    private int endIndex = 0;

    @Override
    public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
        if (tag.equals("articlelink")) {
            if (opening) {
                startIndex = output.length();
                DebugLog.d("OPEN " + startIndex);
            } else {
                endIndex = output.length();
                DebugLog.d("END " + endIndex);
                MyClickableSpan span = new MyClickableSpan();
                output.setSpan(span, startIndex, endIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是日志是:

OPEN 0
OPEN 13
END 18
END 18
Run Code Online (Sandbox Code Playgroud)

但是,在我在字符串之前插入一个字符后,输出就是我所期望的:

串:

"a<articlelink>text1</articlelink> padding<articlelink>text2</articlelink>"
Run Code Online (Sandbox Code Playgroud)

OUTPUT:

OPEN 1
END 6
OPEN 14
END 19
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?这是一个错误还是我误用了它?

小智 10

我通过添加到字符串"零宽度连接器"的开头解决了这个问题

字符串看起来像:

"&zwj;<articlelink>text1</articlelink>padding<articlelink>text2</articlelink>"
Run Code Online (Sandbox Code Playgroud)

在结果textview中,此符号不可见,文本看起来像原始字符串


Cos*_*adu 2

我在编写自定义 TagHandler 时也遇到了这个问题。在我看来,这就像一个 Android 错误。尽管这个问题很旧,因为关于这个问题的信息并不多,我仍然会发布我的解决方案......它可能会对某人有所帮助。

当文本以 HTML 标记(索引 0)开始时,就会出现有问题的情况,当处理到达文本末尾时,将触发带有结束标志的“handleTag()”回调。

我针对这个问题的(有点丑陋的)解决方法是使用单独的标签来打开和关闭标记,例如:

"<start>text1<end> padding<start>text2<end>"
Run Code Online (Sandbox Code Playgroud)

请注意,“结束”标记不是结束标记(它前面没有“/”)。

通过这样做,您将需要更改handleTag()方法中的逻辑,其一般形式如下:

public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
    if (tag.equalsIgnoreCase("start")) {
        // Handle opening of your tag
    } else if (tag.equalsIgnoreCase("end")) {
        // Handle closing of your tag
    }
}
Run Code Online (Sandbox Code Playgroud)

不再需要布尔“开始”参数,并且 output.length() 也将正确返回,因为问题仅与结束标记有关,您将不会使用该结束标记。