Skip to content

Instantly share code, notes, and snippets.

@AndroidT
Last active December 30, 2020 12:55
Show Gist options
  • Select an option

  • Save AndroidT/97bf92f94cadf8f7af72 to your computer and use it in GitHub Desktop.

Select an option

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
Copy Markdown

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)

@faizan-shergill
Copy link
Copy Markdown

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