问题
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:
http://i.imgur.com/Gr3WtyY.png
回答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("..."));
来源:https://stackoverflow.com/questions/24068753/adding-imagespan-after-html-fromhtml