Skip to content

Instantly share code, notes, and snippets.

@AndroidT
Last active December 30, 2020 12:55
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save AndroidT/97bf92f94cadf8f7af72 to your computer and use it in GitHub Desktop.
Save AndroidT/97bf92f94cadf8f7af72 to your computer and use it in GitHub Desktop.
GlideImageGetter uses Glide Image Library to load GIFs/JPG/PNG in HTML <img> tags into TextView
package com.example.name;
import android.content.Context;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.text.Html;
import android.view.View;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
import com.bumptech.glide.request.Request;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.animation.GlideAnimation;
import com.bumptech.glide.request.target.Target;
import com.bumptech.glide.request.target.ViewTarget;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public final class GlideImageGetter implements Html.ImageGetter, Drawable.Callback {
private final Context mContext;
private final TextView mTextView;
private final Set<ImageGetterViewTarget> mTargets;
public static GlideImageGetter get(View view) {
return (GlideImageGetter)view.getTag(R.id.drawable_callback_tag);
}
public void clear() {
GlideImageGetter prev = get(mTextView);
if (prev == null) return;
for (ImageGetterViewTarget target : prev.mTargets) {
Glide.clear(target);
}
}
public GlideImageGetter(Context context, TextView textView) {
this.mContext = context;
this.mTextView = textView;
clear();
mTargets = new HashSet<>();
mTextView.setTag(R.id.drawable_callback_tag, this);
}
@Override
public Drawable getDrawable(String url) {
final UrlDrawable urlDrawable = new UrlDrawable();
System.out.println("Downloading from: " + url);
Glide.with(mContext)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(new ImageGetterViewTarget(mTextView, urlDrawable));
return urlDrawable;
}
@Override
public void invalidateDrawable(Drawable who) {
mTextView.invalidate();
}
@Override
public void scheduleDrawable(Drawable who, Runnable what, long when) {
}
@Override
public void unscheduleDrawable(Drawable who, Runnable what) {
}
private class ImageGetterViewTarget extends ViewTarget<TextView, GlideDrawable> {
private final UrlDrawable mDrawable;
private ImageGetterViewTarget(TextView view, UrlDrawable drawable) {
super(view);
mTargets.add(this);
this.mDrawable = drawable;
}
@Override
public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) {
Rect rect;
if (resource.getIntrinsicWidth() > 100) {
float width;
float height;
System.out.println("Image width is " + resource.getIntrinsicWidth());
System.out.println("View width is " + view.getWidth());
if (resource.getIntrinsicWidth() >= getView().getWidth()) {
float downScale = (float) resource.getIntrinsicWidth() / getView().getWidth();
width = (float) resource.getIntrinsicWidth() / (float) downScale;
height = (float) resource.getIntrinsicHeight() / (float) downScale;
} else {
float multiplier = (float) getView().getWidth() / resource.getIntrinsicWidth();
width = (float) resource.getIntrinsicWidth() * (float) multiplier;
height = (float) resource.getIntrinsicHeight() * (float) multiplier;
}
System.out.println("New Image width is " + width);
rect = new Rect(0, 0, Math.round(width), Math.round(height));
} else {
rect = new Rect(0, 0, resource.getIntrinsicWidth() * 2, resource.getIntrinsicHeight() * 2);
}
resource.setBounds(rect);
mDrawable.setBounds(rect);
mDrawable.setDrawable(resource);
if (resource.isAnimated()) {
mDrawable.setCallback(get(getView()));
resource.setLoopCount(GlideDrawable.LOOP_FOREVER);
resource.start();
}
getView().setText(getView().getText());
getView().invalidate();
}
private Request request;
@Override
public Request getRequest() {
return request;
}
@Override
public void setRequest(Request request) {
this.request = request;
}
}
}
@tasneembohra
Copy link

tasneembohra commented Dec 21, 2016

Hi, what does the code mean over here getView().setText(getView().getText()); Isn't it same ?

It's throwing exception for some device Nexus 5X

Fatal Exception: java.lang.IndexOutOfBoundsException: setSpan (-1 ... -1) starts before 0 at android.text.SpannableStringInternal.checkRange(SpannableStringInternal.java:434) at android.text.SpannableStringInternal.setSpan(SpannableStringInternal.java:155) at android.text.SpannableString.setSpan(SpannableString.java:46) at android.text.Selection.setSelection(Selection.java:76) at android.widget.Editor$SelectionModifierCursorController.resetDragAcceleratorState(Editor.java:5462) at android.widget.Editor$SelectionModifierCursorController.resetTouchOffsets(Editor.java:5452) at android.widget.Editor.sendOnTextChanged(Editor.java:1260) at android.widget.TextView.sendOnTextChanged(TextView.java:8191) at android.widget.TextView.setText(TextView.java:4483) at android.widget.TextView.setText(TextView.java:4337) at android.widget.TextView.setText(TextView.java:4312)

@Flash91FS
Copy link

Was the issue solved or is it still there?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment