8

I am trying to use TextView to display a String text with custom tags:

The String:

"<articlelink>text1</articlelink> padding<articlelink>text2</articlelink>"

Where articlelink is a custom tag. I use a customized HTML.TagHandler to handle the tags:

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);
            }
        }
    }
}

However the log is:

OPEN 0
OPEN 13
END 18
END 18

However, after I insert a character before the string then the output is what I expected:

String:

"a<articlelink>text1</articlelink> padding<articlelink>text2</articlelink>"

OUTPUT:

OPEN 1
END 6
OPEN 14
END 19

What happened here? Is this a bug or I misused it?

darklord
  • 5,077
  • 12
  • 40
  • 65
  • "There is no space in the tag. I have to place the space to make StackOverFlow display it" -- please format it as source code and get rid of any characters that are not really there at runtime. – CommonsWare May 09 '14 at 16:14
  • 1
    Im actually seeing this same issue. Haven't found a solution. Did you? – IZI_Shadow_IZI Jun 05 '14 at 21:49
  • Unfortunately not. This seems likely a bug. Actually I turned to WebView to display the HTML data because there is no way to extract the attributes in the tags with the handleTag() function. – darklord Jun 05 '14 at 22:30
  • How did you manage it to be correct? I didn't get you when you said you inserted a character before the string? – IZI_Shadow_IZI Jun 05 '14 at 23:08
  • @IZI_Shadow_IZI Sorry there is a typo, I have fixed it. I added an 'a' before the whole string if you noticed. That means, if a tag is at the very beginning of the string, error will happen. – darklord Jun 05 '14 at 23:58
  • @IZI_Shadow_IZI By the way, you cannot insert white spaces in the tag. – darklord Jun 06 '14 at 00:03
  • @darklord haha yeah that was my first thought. Sucks that this is a bug that doesnt seem to really have a solution – IZI_Shadow_IZI Jun 06 '14 at 14:34

3 Answers3

15

I solved this problem by adding to the beginning of the string "zero width joiner"

String looks like:

"&zwj;<articlelink>text1</articlelink>padding<articlelink>text2</articlelink>"

In result textview, this symbol is not visible and text looks like the original string

user2536544
  • 151
  • 1
  • 4
2

I have also encountered this issue while writing my custom TagHandler. This seems to me like an Android bug. Even though the question is old, because there isn't really much info on this issue out there, I will still post my solution... it may help someone.

The problematic case appears when the text starts with the HTML tag (at index 0), the callback to "handleTag()" with the closing flag will be triggered when processing reaches the end of the text.

My (kind of ugly) workaround for this problem was to use separate tags for opening and closing marks, like:

"<start>text1<end> padding<start>text2<end>"

Notice the "end" tag is not a closing one (it is not preceded by "/").

By doing this, you will need to change your logic in the handleTag() method, with the following general form:

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
    }
}

The boolean "opening" parameter is no longer needed, and also the output.length() will be correctly returned since the problem is only with the closing tag, which you won't be using.

Cosmin Radu
  • 423
  • 3
  • 11
  • `handleTag` will be called again for the custom closing tag with `opening` set to `false` when it reaches the end of the string. This caused my implementation to crash. So it's safer to check `opening` is `true` before handling the tag. – Elyes Mansour Jul 29 '20 at 13:04
1

Ran into this issue as well, what seems to work is to wrap the text in <html>...</html> tags. That way the html tag will be the one that gets closed last anyway and the rest of the enclosed tags will work fine.

okacat
  • 476
  • 5
  • 6