2

I'm using Html.fromHtml to get the contents of a description tag (in a feed XML) and it works fine

Description tag:

<description><![CDATA[<div class="K2FeedIntroText"><p><img style="margin: 10px; float: left;" alt="block curta" src="http://loc.grupolusofona.pt/images/stories/destaques/block%20curta.jpg" height="110" width="120" />Quatro Horas Descalço é o nome da curta-metragem, realizada por Ico Costa, que se estreia mundialmente no 7.º Festival Internacional de Cinema de Roma, nos dias 12 e 13 de novembro, em competição no Cinema XXI.</p>

]]>

But as I go look into the documentation it says:

Returns displayable styled text from the provided HTML string. Any <img> tags in the HTML will display as a generic replacement image which your program can then go through and replace with real images.

So my question is: how can i do what it says there "which your program can then go through and replace with the real image" ?

I know how to get the img url via RegEx using a Pattern, i just wanted to know how can i use the class to "go through and replace it with the image"

Please say something if i was unclear and ill try to explain it better.

EDIT:

Well, i'm trying to implement this in a simple rss reader (and trying to keep it as simple as possible code-wise)

I'm using a DOM Parser and i'm using a map = HashMap<String, Spanned> to store the values of each child node, along with a KEY:

map.put(KEY_DESC, Html.fromHtml(parser.getValue(e, KEY_DESC)));

In the comments of the answer i found a useful link from which i created a new Class (URLImageParser) and tried to use it like so:

map.put(KEY_DESC, htmlSpan);

Where htmlSpan would be the result of:

this.textView = (TextView)this.findViewById(R.id.textview);
URLImageParser p = new URLImageParser(textView, this);
Spanned htmlSpan = Html.fromHtml(html, p, null);
textView.setText(htmlSpan);

I also created a android:visibility="gone" TextView just in case it needed to store the values in a TextView (maybe i interpreted it wrong)

My original thought was that htmlSpan was of the type Spanned so it would fit in my HashMap just fine.

For uploading to ListView i'm using a SimpleAdapter like so:

    ListAdapter adapter = new SimpleAdapter(this, menuItems, R.layout.linhafeed, 
            new String[] { KEY_TITLE, KEY_DESC, KEY_PUBDATE, KEY_LINK },
            new int[] { R.id.title, R.id.desc, R.id.pub, R.id.link });

Where menuItems is ArrayList<HashMap<String,Spanned>>

Something i got wrong here ?

Community
  • 1
  • 1
jsfrocha
  • 1,812
  • 2
  • 21
  • 32

1 Answers1

3

Html.fromHtml(...) will replace any <img ... /> tag with an ImageSpan and a special 'object replacement character' (\uFFFC).

To get the actual image to show up, it looks like there are two options:

  • implement an ImageGetter that returns the image to display as a Drawable. If I recall correctly, this won't allow you to offload the image loading to a different thread, because it expects the result to be returned right away. Hence, this should suffice for local resources (and probably also any assets in a device's local storage, provided there are no potentially long-running operations required; i.e. scaling, cropping, applying effects etc).
  • do a second pass over the Spanned result and replace any \uFFFC occurrences. You should be able to get the source (url) of the image from every ImageSpan using the getSource() method. Unfortunately, it doesn't look there are any setters to update the Drawable once loaded, so I'm guessing you may need to replace the ImageSpan with a new one, passing in the loaded image in the constructor.

A third alternative, which may be a bit more heavy-weight than above, is to use a WebView rather than a TextView. That way you don't have to deal with any of the image loading yourself, as it's built into the widget.

MH.
  • 45,303
  • 10
  • 103
  • 116
  • On the first point, the ImageGetter, let's suppose i'd return the image as a `Drawable`. I would have to put it in an `ImageView` or could i put it in the place of the `object replacement character` and how ? – jsfrocha Nov 07 '12 at 07:07
  • @jsfrocha: No, you'd just return the `Drawable` that will be displayed inside the `ImageSpan` - no need to use an `ImageView`, which can't be placed inside a `TextView` anyhow. [Here's an example](http://stackoverflow.com/a/4821151/1029225). It appears someone here on SO came up with an [`ImageGetter` that loads your images in the background](http://stackoverflow.com/a/7442725/1029225) by the way - probably worth checking out. – MH. Nov 07 '12 at 07:26
  • So i tried [link](http://stackoverflow.com/q/7424512/1779071) this solution by @momo and it compiles, runs, and doesnt mid-crash, but no image appears. It probably has something to do with where i'm implementing it. Maybe i should've mentioned it in the original question.. gonna edit it.. – jsfrocha Nov 07 '12 at 08:20
  • Any ideas on how to do this ? – jsfrocha Nov 08 '12 at 08:24
  • Based on the snippets given, I can't really tell where it's going wrong. I'm guessing it might be because of the way you create the spans - I'd try moving the whole `Html.fromHtml(...)` part into a custom adapter. However, perhaps better is to rethink your approach. It looks like you're trying to populate a list with an thumbnail image with some text next to it. Then why not use an adapter with `ImageView` and `TextView` as row layout? This is a much more standard pattern and there'll be heaps of resources around to guide you. – MH. Nov 12 '12 at 18:18
  • Yeah, i guess i'm going with the custom adapter approach and i'll try to implement the `ImageGetter` that way. – jsfrocha Nov 13 '12 at 11:31
  • If you're going to use a custom adapter and work with `ImageView`s for the images then there's no need for an actual `ImageGetter` anymore. Obviously you'll still want something that retrieves the images in the background, which is usually called an 'image loader'. A commonly used one is [Android Universal Image Loader](https://github.com/nostra13/Android-Universal-Image-Loader). It should require minimal effort to get to work. – MH. Nov 13 '12 at 18:19
  • Actually what i really wanted was to figure out how `ImageGetter` works, as an actual alternative to image loaders. – jsfrocha Nov 14 '12 at 19:47