Created
June 19, 2014 19:11
-
-
Save lzanita09/d9a81f12f1f223b2f32b to your computer and use it in GitHub Desktop.
ImageSpan subclass that can resize the image to fit the cantainer's width if possible, and recalculate the Rect to avoid overlay text.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.graphics.Paint; | |
import android.graphics.Rect; | |
import android.graphics.drawable.Drawable; | |
import android.text.style.ImageSpan; | |
import java.lang.ref.WeakReference; | |
/** | |
* Subclass of ImageSpan that resizes images automatically to fit the container's width, and then | |
* re-calculate the size of the image to let TextView know how much space it needs to display | |
* the resized image. | |
* | |
* Created by zhelu on 6/16/14. | |
*/ | |
public class ResizeImageSpan extends ImageSpan { | |
private static final int MIN_SCALE_WIDTH = 240; | |
// TextView's width. | |
private int mContainerWidth; | |
public ResizeImageSpan(Drawable d, String source, int containerWidth) { | |
super(d, source); | |
mContainerWidth = containerWidth; | |
} | |
@Override | |
public int getSize(Paint paint, CharSequence text, int start, int end, | |
Paint.FontMetricsInt fm) { | |
Drawable d = getCachedDrawable(); | |
Rect rect = getResizedDrawableBounds(d); | |
if (fm != null) { | |
fm.ascent = -rect.bottom; | |
fm.descent = 0; | |
fm.top = fm.ascent; | |
fm.bottom = 0; | |
} | |
return rect.right; | |
} | |
private Rect getResizedDrawableBounds(Drawable d) { | |
if (d == null || d.getIntrinsicWidth() == 0) { | |
return new Rect(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight()); | |
} | |
int scaledHeight; | |
if (d.getIntrinsicWidth() < mContainerWidth ) { | |
// Image smaller than container's width. | |
if (d.getIntrinsicWidth() > MIN_SCALE_WIDTH && | |
d.getIntrinsicWidth() >= d.getIntrinsicHeight()) { | |
// But larger than the minimum scale size, we need to scale the image to fit | |
// the width of the container. | |
int scaledWidth = mContainerWidth; | |
scaledHeight = d.getIntrinsicHeight() * scaledWidth / d.getIntrinsicWidth(); | |
d.setBounds(0, 0, scaledWidth, scaledHeight); | |
} else { | |
// Smaller than the minimum scale size, leave it as is. | |
d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight()); | |
} | |
} else { | |
// Image is larger than the container's width, scale down to fit the container. | |
int scaledWidth = mContainerWidth; | |
scaledHeight = d.getIntrinsicHeight() * scaledWidth / d.getIntrinsicWidth(); | |
d.setBounds(0, 0, scaledWidth, scaledHeight); | |
} | |
return d.getBounds(); | |
} | |
private Drawable getCachedDrawable() { | |
WeakReference<Drawable> wr = mDrawableRef; | |
Drawable d = null; | |
if (wr != null) { | |
d = wr.get(); | |
} | |
if (d == null) { | |
d = getDrawable(); | |
mDrawableRef = new WeakReference<Drawable>(d); | |
} | |
return d; | |
} | |
private WeakReference<Drawable> mDrawableRef; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment