Created
November 4, 2015 03:25
-
-
Save soeminnminn/dbd7035719ac95979b1e to your computer and use it in GitHub Desktop.
Android Drawable with scale type.
This file contains 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
package com.s16.drawing; | |
import java.io.FileNotFoundException; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.util.List; | |
import android.annotation.SuppressLint; | |
import android.content.ContentResolver; | |
import android.content.Context; | |
import android.content.pm.PackageManager.NameNotFoundException; | |
import android.content.res.Resources; | |
import android.graphics.Bitmap; | |
import android.graphics.BitmapFactory; | |
import android.graphics.Canvas; | |
import android.graphics.ColorFilter; | |
import android.graphics.Matrix; | |
import android.graphics.Paint; | |
import android.graphics.Path; | |
import android.graphics.Rect; | |
import android.graphics.RectF; | |
import android.graphics.drawable.BitmapDrawable; | |
import android.graphics.drawable.Drawable; | |
import android.net.Uri; | |
import android.os.Build; | |
import android.text.TextUtils; | |
import android.view.View; | |
@SuppressLint("UseSparseArrays") | |
public class ScaleTypeDrawable extends Drawable { | |
protected static final String TAG = ScaleTypeDrawable.class.getSimpleName(); | |
private static final int TRANSPARENT = 0x00000000; | |
public enum ScaleType { | |
MATRIX(0), | |
FIT_XY(1), | |
FIT_START(2), | |
FIT_CENTER(3), | |
FIT_END(4), | |
FIT_WIDTH(5), | |
FIT_HEIGHT(6), | |
TILE(7), | |
CENTER(8), | |
CENTER_CROP(9), | |
CENTER_INSIDE(10), | |
SQUARE(11), | |
SQUARE_CENTER(12), | |
CIRCLE(13), | |
CIRCLE_CENTER(14); | |
ScaleType(int ni) { | |
nativeInt = ni; | |
} | |
final int nativeInt; | |
} | |
private static class OpenResourceIdResult { | |
Resources r; | |
int id; | |
} | |
private int mDrawableWidth = -1; | |
private int mDrawableHeight = -1; | |
private Matrix mMatrix; | |
private Matrix mDrawMatrix = null; | |
private final Context mContext; | |
private final Resources mResources; | |
private Drawable mDrawable = null; | |
private Path mPath; | |
private float mCornerRadius; | |
private Paint mBorderPaint; | |
private int mBorderColor; | |
private float mBorderWidth; | |
private Uri mUri; | |
private int mBackgroundColor = 0x0; | |
private ScaleType mScaleType = ScaleType.CENTER; | |
private static final Matrix.ScaleToFit[] sS2FArray = { | |
Matrix.ScaleToFit.FILL, | |
Matrix.ScaleToFit.START, | |
Matrix.ScaleToFit.CENTER, | |
Matrix.ScaleToFit.END | |
}; | |
public static void setHardwareAccelerated(View view, boolean enabled) { | |
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){ | |
if(enabled) | |
view.setLayerType(View.LAYER_TYPE_HARDWARE, null); | |
else view.setLayerType(View.LAYER_TYPE_SOFTWARE, null); | |
} | |
} | |
public ScaleTypeDrawable(Context context, int resId) { | |
this(context, context.getResources().getDrawable(resId)); | |
} | |
public ScaleTypeDrawable(Context context, String filepath) { | |
this(context, BitmapFactory.decodeFile(filepath)); | |
} | |
public ScaleTypeDrawable(Context context, java.io.InputStream is) { | |
this(context, BitmapFactory.decodeStream(is)); | |
} | |
public ScaleTypeDrawable(Context context, Bitmap bitmap) { | |
this(context, new BitmapDrawable(context.getResources(), bitmap)); | |
} | |
public ScaleTypeDrawable(Context context, Drawable srcDrawable) { | |
mContext = context; | |
mResources = context.getResources(); | |
init(); | |
if (srcDrawable != null) { | |
mDrawable = srcDrawable; | |
mDrawableWidth = srcDrawable.getIntrinsicWidth(); | |
mDrawableHeight = srcDrawable.getIntrinsicHeight(); | |
} | |
} | |
public ScaleTypeDrawable(Context context, Uri uri) { | |
mContext = context; | |
mResources = context.getResources(); | |
mUri = uri; | |
init(); | |
resolveUri(); | |
} | |
private void init() { | |
mMatrix = new Matrix(); | |
mBorderPaint = new Paint(); | |
mBorderPaint.setAntiAlias(true); | |
mBorderPaint.setStyle(Paint.Style.FILL); | |
mBorderPaint.setColor(TRANSPARENT); | |
} | |
protected void resolveUri() { | |
if (mUri != null) { | |
String scheme = mUri.getScheme(); | |
if (ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme)) { | |
// android.resource://[package]/[res id] | |
// android.resource://[package]/[res type]/[res name] | |
try { | |
// Load drawable through Resources, to get the source density information | |
OpenResourceIdResult r = getResourceId(mContext, mUri); | |
mDrawable = r.r.getDrawable(r.id); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
} else if (ContentResolver.SCHEME_CONTENT.equals(scheme) | |
|| ContentResolver.SCHEME_FILE.equals(scheme)) { | |
InputStream stream = null; | |
try { | |
stream = mContext.getContentResolver().openInputStream(mUri); | |
mDrawable = Drawable.createFromStream(stream, null); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} finally { | |
if (stream != null) { | |
try { | |
stream.close(); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
} | |
} else { | |
mDrawable = Drawable.createFromPath(mUri.toString()); | |
} | |
if (mDrawable == null) { | |
System.out.println("resolveUri failed on bad bitmap uri: " + mUri); | |
// Don't try again. | |
mUri = null; | |
} | |
} | |
} | |
protected static OpenResourceIdResult getResourceId(Context context, Uri uri) | |
throws FileNotFoundException { | |
String authority = uri.getAuthority(); | |
Resources r; | |
if (TextUtils.isEmpty(authority)) { | |
throw new FileNotFoundException("No authority: " + uri); | |
} else { | |
try { | |
r = context.getPackageManager().getResourcesForApplication(authority); | |
} catch (NameNotFoundException ex) { | |
throw new FileNotFoundException("No package found for authority: " + uri); | |
} | |
} | |
List<String> path = uri.getPathSegments(); | |
if (path == null) { | |
throw new FileNotFoundException("No path: " + uri); | |
} | |
int len = path.size(); | |
int id; | |
if (len == 1) { | |
try { | |
id = Integer.parseInt(path.get(0)); | |
} catch (NumberFormatException e) { | |
throw new FileNotFoundException("Single path segment is not a resource ID: " + uri); | |
} | |
} else if (len == 2) { | |
id = r.getIdentifier(path.get(1), path.get(0), authority); | |
} else { | |
throw new FileNotFoundException("More than two path segments: " + uri); | |
} | |
if (id == 0) { | |
throw new FileNotFoundException("No resource found for: " + uri); | |
} | |
OpenResourceIdResult res = new OpenResourceIdResult(); | |
res.r = r; | |
res.id = id; | |
return res; | |
} | |
/* Reference */ | |
// BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); | |
// Paint paint = new Paint(); | |
// paint.setAntiAlias(true); | |
// paint.setShader(shader); | |
// RectF rect = new RectF(0.0f, 0.0f, width, height); | |
// // rect contains the bounds of the shape | |
// // radius is the radius in pixels of the rounded corners | |
// // paint contains the shader that will texture the shape | |
// canvas.drawRoundRect(rect, radius, radius, paint); | |
@Override | |
public void draw(Canvas canvas) { | |
if (mDrawable == null) { | |
return; // couldn't resolve the URI | |
} | |
if (mDrawableWidth == 0 || mDrawableHeight == 0) { | |
return; // nothing to draw (empty bounds) | |
} | |
RectF rectPaint = new RectF(); | |
rectPaint.set(getBounds()); | |
if (rectPaint.width() == 0 || rectPaint.height() == 0) { | |
return; | |
} | |
int saveCount = canvas.save(); | |
if (mBackgroundColor != 0) { | |
canvas.drawColor(mBackgroundColor); | |
} | |
//Log.i(TAG, "isHardwareAccelerated=" + canvas.isHardwareAccelerated()); | |
if (mBorderWidth > 0.0f) { | |
RectF rectBorder = getDrawRect(rectPaint.width(), rectPaint.height(), mDrawableWidth, mDrawableHeight, 0.0f); | |
Path borderPath = getDrawPath(rectBorder, rectBorder.width(), rectBorder.height(), mCornerRadius, 0.0f); | |
canvas.translate(rectBorder.left, rectBorder.top); | |
canvas.drawPath(borderPath, mBorderPaint); | |
canvas.restoreToCount(saveCount); | |
saveCount = canvas.save(); | |
Path bitmapPath = getDrawPath(rectPaint, mDrawableWidth, mDrawableHeight, mCornerRadius, mBorderWidth); | |
if (bitmapPath != null) { | |
canvas.clipPath(bitmapPath); | |
} | |
} else { | |
Path bitmapPath = getDrawPath(rectPaint, mDrawableWidth, mDrawableHeight, mCornerRadius, 0.0f); | |
if (bitmapPath != null) { | |
canvas.clipPath(bitmapPath); | |
} | |
} | |
if (mDrawMatrix != null) { | |
canvas.concat(mDrawMatrix); | |
} | |
if (ScaleType.TILE == mScaleType) { | |
drawTileBitmap(canvas, rectPaint, mDrawableWidth, mDrawableHeight, mBorderWidth); | |
} else { | |
mDrawable.draw(canvas); | |
} | |
canvas.restoreToCount(saveCount); | |
} | |
protected void drawTileBitmap(Canvas canvas, RectF bounds, float dwidth, float dheight, float padding) { | |
if (mDrawable == null) { | |
return; | |
} | |
float vwidth = bounds.width(); | |
float vheight = bounds.height(); | |
float x = bounds.left; | |
float y = bounds.top; | |
for(; x < bounds.left+vwidth; x+=dwidth) { | |
for(;y < bounds.top+vheight; y+=dheight) { | |
int saveCount = canvas.save(); | |
canvas.translate(x, y); | |
mDrawable.draw(canvas); | |
canvas.restoreToCount(saveCount); | |
} | |
y = bounds.top; | |
} | |
} | |
@Override | |
protected void onBoundsChange(Rect bounds) { | |
super.onBoundsChange(bounds); | |
configureBounds(bounds); | |
} | |
protected void updateDrawable() { | |
Rect bounds = getBounds(); | |
configureBounds(bounds); | |
invalidateSelf(); | |
} | |
protected static Matrix.ScaleToFit scaleTypeToScaleToFit(ScaleType st) { | |
// ScaleToFit enum to their corresponding Matrix.ScaleToFit values | |
return sS2FArray[st.nativeInt - 1]; | |
} | |
protected void configureBounds(Rect bounds) { | |
if (mDrawable == null) { | |
return; | |
} | |
int dwidth = mDrawableWidth; | |
int dheight = mDrawableHeight; | |
int vwidth = bounds.width(); | |
int vheight = bounds.height(); | |
boolean fits = (dwidth < 0 || vwidth == dwidth) && | |
(dheight < 0 || vheight == dheight); | |
if (dwidth <= 0 || dheight <= 0 || ScaleType.FIT_XY == mScaleType) { | |
/* If the drawable has no intrinsic size, or we're told to | |
scaletofit, then we just fill our entire view. | |
*/ | |
mDrawable.setBounds(0, 0, vwidth, vheight); | |
mDrawMatrix = null; | |
} else { | |
// We need to do the scaling ourself, so have the drawable | |
// use its native size. | |
mDrawable.setBounds(0, 0, dwidth, dheight); | |
if (mScaleType == ScaleType.MATRIX) { | |
// Use the specified matrix as-is. | |
if (mMatrix.isIdentity()) { | |
mDrawMatrix = null; | |
} else { | |
mDrawMatrix = mMatrix; | |
} | |
} else if (fits) { | |
// The bitmap fits exactly, no transform needed. | |
mDrawMatrix = null; | |
} else if (mScaleType == ScaleType.CENTER) { | |
// Center bitmap in view, no scaling. | |
mDrawMatrix = mMatrix; | |
mDrawMatrix.setTranslate((int) ((vwidth - dwidth) * 0.5f + 0.5f), | |
(int) ((vheight - dheight) * 0.5f + 0.5f)); | |
} else if (ScaleType.CENTER_CROP == mScaleType) { | |
mDrawMatrix = mMatrix; | |
float scale; | |
float dx = 0, dy = 0; | |
if (dwidth * vheight > vwidth * dheight) { | |
scale = (float) vheight / (float) dheight; | |
dx = (vwidth - dwidth * scale) * 0.5f; | |
} else { | |
scale = (float) vwidth / (float) dwidth; | |
dy = (vheight - dheight * scale) * 0.5f; | |
} | |
mDrawMatrix.setScale(scale, scale); | |
mDrawMatrix.postTranslate((int) (dx + 0.5f), (int) (dy + 0.5f)); | |
} else if (mScaleType == ScaleType.CENTER_INSIDE) { | |
mDrawMatrix = mMatrix; | |
float scale; | |
float dx; | |
float dy; | |
if (dwidth <= vwidth && dheight <= vheight) { | |
scale = 1.0f; | |
} else { | |
scale = Math.min((float) vwidth / (float) dwidth, | |
(float) vheight / (float) dheight); | |
} | |
dx = (int)((vwidth - dwidth * scale) * 0.5f + 0.5f); | |
dy = (int)((vheight - dheight * scale) * 0.5f + 0.5f); | |
mDrawMatrix.setScale(scale, scale); | |
mDrawMatrix.postTranslate(dx, dy); | |
} else if (mScaleType == ScaleType.FIT_HEIGHT) { // Fit Height | |
mDrawMatrix = mMatrix; | |
float scale = (float)vheight / (float)dheight; | |
float dx = (int)((vwidth - dwidth * scale) * 0.5f + 0.5f); | |
float dy = 0; | |
mDrawMatrix.setScale(scale, scale); | |
mDrawMatrix.postTranslate(dx, dy); | |
} else if (mScaleType == ScaleType.FIT_WIDTH) { // Fit Width | |
mDrawMatrix = mMatrix; | |
float scale = (float)vwidth / (float)dwidth; | |
float dx = 0; | |
float dy = (int)((vheight - dheight * scale) * 0.5f + 0.5f); | |
mDrawMatrix.setScale(scale, scale); | |
mDrawMatrix.postTranslate(dx, dy); | |
} else if (mScaleType == ScaleType.TILE) { | |
mDrawMatrix = null; | |
} else if (mScaleType == ScaleType.CIRCLE || mScaleType == ScaleType.SQUARE) { | |
mDrawMatrix = mMatrix; | |
float size = Math.min(vwidth, vheight); | |
float scale; | |
float dx = 0, dy = 0; | |
if (dwidth > dheight) { | |
scale = (float) size / (float) dheight; | |
} else { | |
scale = (float) size / (float) dwidth; | |
} | |
dx = (int)((vwidth - dwidth * scale) * 0.5f + 0.5f); | |
dy = (int)((vheight - dheight * scale) * 0.5f + 0.5f); | |
mDrawMatrix.setScale(scale, scale); | |
mDrawMatrix.postTranslate(dx, dy); | |
} else if (mScaleType == ScaleType.CIRCLE_CENTER || mScaleType == ScaleType.SQUARE_CENTER) { | |
float size = Math.min(vwidth, vheight); | |
float scale = 0; | |
if (dwidth <= vwidth && dheight <= vheight) { | |
scale = 1.0f; | |
} else { | |
if (dwidth > dheight) { | |
scale = (float)size / (float)dheight; | |
} else { | |
scale = (float)size / (float)dwidth; | |
} | |
} | |
float dx = (int)((vwidth - dwidth * scale) * 0.5f + 0.5f); | |
float dy = (int)((vheight - dheight * scale) * 0.5f + 0.5f); | |
mDrawMatrix = mMatrix; | |
mDrawMatrix.setScale(scale, scale); | |
mDrawMatrix.postTranslate(dx, dy); | |
} else { | |
// Generate the required transform. | |
mDrawMatrix = mMatrix; | |
mDrawMatrix.setRectToRect(new RectF(0, 0, dwidth, dheight), new RectF(0, 0, vwidth, vheight), | |
scaleTypeToScaleToFit(mScaleType)); | |
} | |
} | |
} | |
protected Path getDrawPath(RectF bounds, float dwidth, float dheight, float cornerRadius, float padding) { | |
Path path = null; | |
if (mPath != null) { | |
path = new Path(mPath); | |
} else { | |
path = new Path(); | |
float vwidth = bounds.width(); | |
float vheight = bounds.height(); | |
if (mScaleType == ScaleType.CIRCLE) { | |
float size = Math.min(vwidth, vheight); | |
path.addCircle((vwidth - 1) / 2, | |
(vheight - 1) / 2, | |
(size / 2) - padding, | |
Path.Direction.CCW); | |
} else if (mScaleType == ScaleType.CIRCLE_CENTER) { | |
float size = Math.min(Math.min(vwidth, vheight), Math.min(dwidth, dheight)); | |
path.addCircle((vwidth - 1) / 2, | |
(vheight - 1) / 2, | |
(size / 2) - padding, | |
Path.Direction.CCW); | |
} else { | |
float scale = 1.0f; | |
if (dwidth * vheight > vwidth * dheight) { | |
scale = (float) vwidth / (float) dwidth; | |
} else { | |
scale = (float) vheight / (float) dheight; | |
} | |
RectF rect = new RectF(bounds); | |
if (mScaleType == ScaleType.FIT_START) { | |
rect = new RectF(0, 0, dwidth * scale, dheight * scale); | |
} else if (mScaleType == ScaleType.FIT_CENTER) { | |
float dx = (vwidth - dwidth * scale) * 0.5f; | |
float dy = (vheight - dheight * scale) * 0.5f; | |
rect = new RectF(dx, dy, dx + (dwidth * scale), dy + (dheight * scale)); | |
} else if (mScaleType == ScaleType.FIT_END) { | |
float dx = vwidth - dwidth * scale; | |
float dy = vheight - dheight * scale; | |
rect = new RectF(dx, dy, dx + (dwidth * scale), dy + (dheight * scale)); | |
} else if (mScaleType == ScaleType.FIT_WIDTH) { | |
scale = (float)vwidth / (float)dwidth; | |
float dx = 0; | |
float dy = Math.max(0, (vheight - dheight * scale) * 0.5f + 0.5f); | |
rect = new RectF(dx, dy, | |
dx + Math.min(vwidth, (dwidth * scale)), | |
dy + Math.min(vheight, (dheight * scale))); | |
} else if (mScaleType == ScaleType.FIT_HEIGHT) { | |
scale = (float)vheight / (float)dheight; | |
float dx = Math.max(0, (vwidth - dwidth * scale) * 0.5f + 0.5f); | |
float dy = 0; | |
rect = new RectF(dx, dy, | |
dx + Math.min(vwidth, (dwidth * scale)), | |
dy + Math.min(vheight, (dheight * scale))); | |
} else if (mScaleType == ScaleType.CENTER) { | |
float dx = 0, dy = 0; | |
if (dwidth <= vwidth && dheight <= vheight) { | |
dy = (vheight - dheight) * 0.5f; | |
dx = (vwidth - dwidth) * 0.5f; | |
} else { | |
if (dwidth * vheight > vwidth * dheight) { | |
dy = (vheight - dheight) * 0.5f; | |
} else { | |
dx = (vwidth - dwidth) * 0.5f; | |
} | |
} | |
rect = new RectF(dx, dy, dx + Math.min(vwidth, dwidth), dy + Math.min(vheight, dheight)); | |
} else if (mScaleType == ScaleType.CENTER_INSIDE) { | |
if (dwidth <= vwidth && dheight <= vheight) { | |
scale = 1.0f; | |
} | |
float dx = (vwidth - dwidth * scale) * 0.5f; | |
float dy = (vheight - dheight * scale) * 0.5f; | |
rect = new RectF(dx, dy, dx + (dwidth * scale), dy + (dheight * scale)); | |
} else if (mScaleType == ScaleType.SQUARE) { | |
float size = Math.min(vwidth, vheight); | |
float dx = (vwidth - size) * 0.5f; | |
float dy = (vheight - size) * 0.5f; | |
rect = new RectF(dx, dy, dx + size, dy + size); | |
} else if (mScaleType == ScaleType.SQUARE_CENTER) { | |
float size = Math.min(Math.min(vwidth, vheight), Math.min(dwidth, dheight)); | |
float dx = (vwidth - size) * 0.5f; | |
float dy = (vheight - size) * 0.5f; | |
rect = new RectF(dx, dy, dx + size, dy + size); | |
} | |
if (padding > 0.0f) { | |
RectF rectWithPadding = new RectF(rect.left + padding, rect.top + padding, rect.right - padding, rect.bottom - padding); | |
if (cornerRadius > 0) { | |
path.addRoundRect(rectWithPadding, cornerRadius, cornerRadius, Path.Direction.CCW); | |
} else { | |
path.addRect(rectWithPadding, Path.Direction.CCW); | |
} | |
} else { | |
if (cornerRadius > 0) { | |
path.addRoundRect(rect, cornerRadius, cornerRadius, Path.Direction.CCW); | |
} else { | |
path.addRect(rect, Path.Direction.CCW); | |
} | |
} | |
} | |
} | |
return path; | |
} | |
protected RectF getDrawRect(float vwidth, float vheight, float dwidth, float dheight, float padding) { | |
float x = 0.0f; | |
float y = 0.0f; | |
float pwidth = vwidth; | |
float pheight = vheight; | |
float width = 0.0f; | |
float height = 0.0f; | |
float scale = 1f; | |
if (dwidth * vheight > vwidth * dheight) { | |
scale = (float)vwidth / (float)dwidth; | |
} else { | |
scale = (float)vheight / (float)dheight; | |
} | |
if (mScaleType == ScaleType.FIT_START) { | |
if (pwidth < pheight) { | |
width = pwidth; | |
height = dheight * scale; | |
} else { | |
width = dwidth * scale; | |
height = pheight; | |
} | |
} else if (mScaleType == ScaleType.FIT_END) { | |
if (vwidth < vheight) { | |
width = pwidth; | |
height = dheight * scale; | |
y += pheight - height; | |
} else { | |
width = dwidth * scale; | |
height = pheight; | |
x += pwidth - width; | |
} | |
} else if (mScaleType == ScaleType.FIT_CENTER) { | |
if (vwidth < vheight) { | |
width = pwidth; | |
height = dheight * scale; | |
y += (pheight - height) * 0.5f; | |
} else { | |
width = dwidth * scale; | |
height = pheight; | |
x += (pwidth - width) * 0.5f; | |
} | |
} else if (mScaleType == ScaleType.FIT_WIDTH) { | |
scale = vwidth / dwidth; | |
width = pwidth; | |
height = Math.min(vheight, dheight * scale); | |
y += (pheight - height) * 0.5f; | |
} else if (mScaleType == ScaleType.FIT_HEIGHT) { | |
scale = vheight / dheight; | |
width = Math.min(vwidth, dwidth * scale); | |
height = pheight; | |
x += (pwidth - width) * 0.5f; | |
} else if (mScaleType == ScaleType.CENTER) { | |
width = Math.min(vwidth, dwidth); | |
height = Math.min(vheight, dheight); | |
y += (pheight - height) * 0.5f; | |
x += (pwidth - width) * 0.5f; | |
} else if (mScaleType == ScaleType.CENTER_INSIDE) { | |
if (dwidth <= pwidth && dheight <= pheight) { | |
width = dwidth; | |
height = dheight; | |
y += (pheight - height) * 0.5f; | |
x += (pwidth - width) * 0.5f; | |
} else if (pwidth < pheight) { | |
width = vwidth; | |
height = dheight * scale; | |
y += (pheight - height) * 0.5f; | |
x = 0.0f; | |
} else { | |
width = dwidth * scale; | |
height = vheight; | |
x += (pwidth - width) * 0.5f; | |
y = 0.0f; | |
} | |
} else if (mScaleType == ScaleType.SQUARE || mScaleType == ScaleType.CIRCLE) { | |
float size = Math.min(dwidth, dheight); | |
if (dwidth * vheight > vwidth * dheight) { | |
scale = (float)pwidth / (float)size; | |
} else { | |
scale = (float)pheight / (float)size; | |
} | |
width = Math.min(pwidth, dwidth * scale); | |
height = Math.min(pheight, dheight * scale); | |
y += (pheight - height) * 0.5f; | |
x += (pwidth - width) * 0.5f; | |
} else if (mScaleType == ScaleType.SQUARE_CENTER || mScaleType == ScaleType.CIRCLE_CENTER) { | |
width = height = Math.min(Math.min(vwidth, vheight), Math.min(dwidth, dheight)); | |
y += (pheight - height) * 0.5f; | |
x += (pwidth - width) * 0.5f; | |
} else { | |
width = pwidth; | |
height = pheight; | |
x = 0.0f; | |
y = 0.0f; | |
} | |
if (padding > 0.0f) { | |
return new RectF(x + padding, y + padding, (x + width) - padding, (y + height) - padding); | |
} | |
return new RectF(x, y, x + width, y + height); | |
} | |
public void setBitmapResource(int resId) { | |
if (resId != 0) { | |
setBitmapDrawable(mResources.getDrawable(resId)); | |
} | |
} | |
public void setBitmap(Bitmap bitmap) { | |
if (bitmap != null) { | |
setBitmapDrawable(new BitmapDrawable(mResources, bitmap)); | |
} | |
} | |
public void setBitmapDrawable(Drawable value) { | |
mDrawable = value; | |
mUri = null; | |
if (value != null) { | |
mDrawableWidth = value.getIntrinsicWidth(); | |
mDrawableHeight = value.getIntrinsicHeight(); | |
updateDrawable(); | |
} else { | |
mDrawableWidth = mDrawableHeight = -1; | |
} | |
} | |
public void setBitmapDrawable(Drawable value, int width, int height) { | |
mDrawable = value; | |
mUri = null; | |
if (value != null) { | |
mDrawableWidth = width; | |
mDrawableHeight = height; | |
updateDrawable(); | |
} else { | |
mDrawableWidth = mDrawableHeight = -1; | |
} | |
} | |
public void setImageURI(Uri uri) { | |
if (mUri != uri && (uri == null || mUri == null || !uri.equals(mUri))) { | |
mUri = uri; | |
resolveUri(); | |
if (mDrawable != null) { | |
mDrawableWidth = mDrawable.getIntrinsicWidth(); | |
mDrawableHeight = mDrawable.getIntrinsicHeight(); | |
updateDrawable(); | |
} else { | |
mDrawableWidth = mDrawableHeight = -1; | |
} | |
} | |
} | |
public void setBorderColor(int borderColor) { | |
if (borderColor == mBorderColor) { | |
return; | |
} | |
mBorderColor = borderColor; | |
mBorderPaint.setColor(mBorderColor); | |
invalidateSelf(); | |
} | |
public void setBorderWidth(float borderWidth) { | |
if (borderWidth == mBorderWidth) { | |
return; | |
} | |
mBorderWidth = borderWidth; | |
mBorderPaint.setStrokeWidth(mBorderWidth); | |
invalidateSelf(); | |
} | |
@Override | |
public void setAlpha(int alpha) { | |
if (mDrawable != null) { | |
mDrawable.setAlpha(alpha); | |
} | |
invalidateSelf(); | |
} | |
@Override | |
public void setColorFilter(ColorFilter cf) { | |
if (mDrawable != null) { | |
mDrawable.setColorFilter(cf); | |
} | |
invalidateSelf(); | |
} | |
@Override | |
public int getOpacity() { | |
return android.graphics.PixelFormat.OPAQUE; | |
} | |
@Override | |
public int getIntrinsicWidth() { | |
return mDrawableWidth; | |
} | |
@Override | |
public int getIntrinsicHeight() { | |
return mDrawableHeight; | |
} | |
public Drawable getSourceDrawable() { | |
return mDrawable; | |
} | |
public void setBackgroundColor(int color) { | |
if (mBackgroundColor != color) { | |
mBackgroundColor = color; | |
invalidateSelf(); | |
} | |
} | |
public int getBackgroundColor() { | |
return mBackgroundColor; | |
} | |
public void setScaleType(ScaleType value) { | |
if (mScaleType != value) { | |
mScaleType = value; | |
updateDrawable(); | |
} | |
} | |
public void setDrawPath(Path path) { | |
mPath = path; | |
updateDrawable(); | |
} | |
public void setCornerRadius(float radius) { | |
if (mCornerRadius != radius) { | |
mCornerRadius = radius; | |
updateDrawable(); | |
} | |
} | |
public Matrix getImageMatrix() { | |
if (mDrawMatrix == null) { | |
return new Matrix(); | |
} | |
return mDrawMatrix; | |
} | |
public void setImageMatrix(Matrix matrix) { | |
// collaps null and identity to just null | |
if (matrix != null && matrix.isIdentity()) { | |
matrix = null; | |
} | |
// don't invalidate unless we're actually changing our matrix | |
if (matrix == null && !mMatrix.isIdentity() || | |
matrix != null && !mMatrix.equals(matrix)) { | |
mMatrix.set(matrix); | |
updateDrawable(); | |
} | |
} | |
public void destroy() { | |
if (mDrawable != null) { | |
mDrawable = null; | |
} | |
System.gc(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment