3

In my Android app I've got text views with links. Each of them is toggling a particular event (opening browser, starting another activity, etc...). To handle that, I haven't found any better solution than doing this:

hi there!, this is <u>a action</u> and this is <b>another action</b>. This third one goes to <a href="http://google.com>Google</a>

Then, when displaying the textview, I convert each link to a custom spannable with a SpannableStringBuilder.

I know this is hacky. And this is why I want to know if there's any other better way?

I've got two ideas:

  • Is it possible to implement custom spannables with their own marshalling system? For example a custom spannable matching tags like:

    <div class="foo"></div>

Then I'd have a FooClickableSpannable extending ClickableSpan automatically detected with fromHtml()

  • I could use custom url schemes to open my activities but I'm not sure how to force it not to display an app chooser if there are other alternatives.
Romain Piel
  • 11,017
  • 15
  • 71
  • 106

1 Answers1

1

Is it possible to implement custom spannables with their own marshalling system?

Can you create custom subclasses of CharacterStyle, particularly ClickableSpan? Yes.

I have no idea what "their own marshalling system" means, though.

I could use custom url schemes to open my activities but I'm not sure how to force it not to display an app chooser if there are other alternatives.

Well, a true custom scheme (e.g., piel:// instead of http:// or content://) is unlikely to present a chooser, since it is unlikely that there will be another alternative.

Beyond that, what I have done in the past is:

  • Use Html.fromHtml() for a basic conversion
  • Use getSpans() on the results to find all the URLSpan objects
  • replaced those URLSpan objects with other sorts of custom spans where needed via removeSpan() and setSpan()

Another approach would be to create a workalike for Html.fromHtml(). This is something that's rattling around the lower levels of my own TODO list, to create something that is more extensible, handles more HTML constructs, etc.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • thanks for this comment, I think your last paragraph is what i want to do in my first suggestion (see my updated question). This is actually very interesting, the data-scheme solution is a quick fix but might not be the cleanest solution. I'll try to see how i can do my Html.fromHtml() workalike. – Romain Piel Oct 21 '12 at 12:27
  • @RomainPiel: Another possibility is to invent totally new tags, if this content will not be viewed outside of your app. So a `...` tag would ordinarily be ignored, but you could attach an `Html.TagHandler` to your `fromHtml()` request to catch that. Unfortunately, `
    ` is already recognized by the parser, and does not distinguish via `class`, so your `TagHandler` would not get control, and that would require a `fromHtml()` workalike. But I notice that `` is not presently used by `fromHtml()`, so that's a more standards-compliant option without you rolling your own parser.
    – CommonsWare Oct 21 '12 at 12:33
  • interesting, didn't know about that TagHandler thing, cheers! – Romain Piel Oct 21 '12 at 17:14