1

I have an JSON String which contains HTML Tags and image like this one:

<center>denn.. <span class="uicon" style="background-image:url(http://static.allmystery.de/images/lachen.gif);width:15px;height:14px;" title=":)">:)</span>
ich habe immer versucht ein <small>perfektionist</small> zu sein ohne das es mir klar war.<br><br>

I tried to replace the smileys with img src= "" tags but its a pain to load them with an ImageGetter.I was successful with Picasso and ImageSpans. My Question is, it is possible to add Imagespans after I used HTML.fromHtml(String)?

I want to display everything in an EditText if it matters.

EDIT:

If someone has the same trouble of displaying images in EditText or TextViews here is my solution to this annoying problem:

SpannableString spannableString = new SpannableString(Html.fromHtml(text));

Pattern p = Pattern.compile(ADD REGEX TO FIND IMAGE URLS);
Matcher m = p.matcher(spannableString);

        while (m.find()) {

            //m.start() will give you the startlocation of the matched string
            //m.end() does the same with the endlocation
            //m.group(1) contains the imageurl which is captured with regex

            //CustomTarget implements Target from Picasso (Imageloading library)
            //holder.postText is the EditText or TextView

            CustomTarget target = new CustomTarget(m.group(1), m.start(), m.end(), holder.postText, spannableString);

            //add target to an ArrayList to keep a strong reference to prevent that the target gets garbage collected
            // before the image is placed into the view
            targets.add(target);

            //load the image into the CustomTarget
            Picasso picasso = Picasso.with(context);
            picasso.setDebugging(true);
            picasso.load(m.group(1)).into(target);
        }

CustomTarget Class:

   private class CustomTarget implements Target {

    String url;
    int start;
    int end;
    WeakReference<EditText> postText;
    SpannableString rawText;


    public CustomTarget(String url, int start, int end, EditText postText, SpannableString rawText) {

        this.url = url;
        this.start = start;
        this.end = end;
        this.postText = new WeakReference<>(postText);
        this.rawText = rawText;

    }

    @Override
    public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {

        //get a weak Reference to the EditText because holder pattern in ListView will replace the View inside the holder before the Async Task is done
        EditText editText = postText.get();

        //Get existing ImageSpans to add them later again, if not, you will only get the last loaded image displayed
        ImageSpan[] spans =  editText.getText().getSpans(0, editText.length(), ImageSpan.class);

        BitmapDrawable d =  new BitmapDrawable(context.getResources(), bitmap);
        d.setBounds(0, 0, d.getIntrinsicWidth()+5, d.getIntrinsicHeight()+5);
        ImageSpan imageSpan = new ImageSpan( d, ImageSpan.ALIGN_BASELINE);

        //add ImageSpan to the SpannableString
        rawText.setSpan(imageSpan, start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE);

        //add previously added ImageSpans
        if (spans.length >= 1) {

            for (ImageSpan image: spans) {


                rawText.setSpan(image, editText.getText().getSpanStart(image), editText.getText().getSpanEnd(image), Spanned.SPAN_INCLUSIVE_INCLUSIVE);

            }

        }
        //add the edited SpannableString to the EditText
        editText.setText(rawText, TextView.BufferType.SPANNABLE);

        //remove target from ArrayList to allow Garbage Collection
        targets.remove(this);

    }

    @Override
    public void onBitmapFailed(Drawable errorDrawable) {

    }

    @Override
    public void onPrepareLoad(Drawable placeHolderDrawable) {

    }
}

NOTE: you should do some resizing if your images are larger

How it looks:

https://i.stack.imgur.com/HCuxU.png

not sure
  • 13
  • 1
  • 4

1 Answers1

1

To add spans, you need a Spannable instance. However, Html.fromHtml() returns a Spanned object, which doesn't provide for this.

This is the interface for text that has markup objects attached to ranges of it. Not all text classes have mutable markup or text; see Spannable for mutable markup and Editable for mutable text.

However, you can create a Spannable from a Spanned, pretty easily. Just use:

SpannableString s = new SpannableString(Html.fromHtml("..."));
matiash
  • 54,791
  • 16
  • 125
  • 154
  • After endless hours of pain with ImageGetter just to display images in an TextView or EditText this was the solution. Thank you, I able to die happy now. – not sure Jun 06 '14 at 13:06
  • @notsure You're welcome. Make sure that doesn't happen too soon. ;) – matiash Jun 06 '14 at 15:28