package org.qii.weiciyuan.support.lib;
import org.qii.weiciyuan.support.utils.Utility;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
import android.widget.ImageView;
/**
* User: qii
* Date: 14-4-1
*/
public class AnimationRect implements Parcelable {
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(scaledBitmapRect, flags);
dest.writeParcelable(imageViewEntireRect, flags);
dest.writeParcelable(imageViewVisibleRect, flags);
dest.writeInt(type);
dest.writeBooleanArray(new boolean[]{isTotalVisible});
dest.writeBooleanArray(new boolean[]{isTotalInvisible});
dest.writeBooleanArray(new boolean[]{isScreenPortrait});
dest.writeFloat(thumbnailWidthHeightRatio);
dest.writeInt(thumbnailWidth);
dest.writeInt(thumbnailHeight);
dest.writeInt(widgetWidth);
dest.writeInt(widgetHeight);
dest.writeFloat(clipByParentRectTop);
dest.writeFloat(clipByParentRectBottom);
dest.writeFloat(clipByParentRectLeft);
dest.writeFloat(clipByParentRectRight);
}
public static final Parcelable.Creator<AnimationRect> CREATOR =
new Parcelable.Creator<AnimationRect>() {
public AnimationRect createFromParcel(Parcel in) {
AnimationRect rect = new AnimationRect();
rect.scaledBitmapRect = in.readParcelable(Rect.class.getClassLoader());
rect.imageViewEntireRect = in.readParcelable(Rect.class.getClassLoader());
rect.imageViewVisibleRect = in.readParcelable(Rect.class.getClassLoader());
rect.type = in.readInt();
boolean[] booleans = new boolean[1];
in.readBooleanArray(booleans);
rect.isTotalVisible = booleans[0];
boolean[] isTotalInvisibleBooleans = new boolean[1];
in.readBooleanArray(isTotalInvisibleBooleans);
rect.isTotalInvisible = isTotalInvisibleBooleans[0];
boolean[] isScreenPortraitArray = new boolean[1];
in.readBooleanArray(isScreenPortraitArray);
rect.isScreenPortrait = isScreenPortraitArray[0];
rect.thumbnailWidthHeightRatio = in.readFloat();
rect.thumbnailWidth = in.readInt();
rect.thumbnailHeight = in.readInt();
rect.widgetWidth = in.readInt();
rect.widgetHeight = in.readInt();
rect.clipByParentRectTop = in.readFloat();
rect.clipByParentRectBottom = in.readFloat();
rect.clipByParentRectLeft = in.readFloat();
rect.clipByParentRectRight = in.readFloat();
return rect;
}
public AnimationRect[] newArray(int size) {
return new AnimationRect[size];
}
};
public static final int TYPE_CLIP_V = 0;
public static final int TYPE_CLIP_H = 1;
public static final int TYPE_EXTEND_V = 2;
public static final int TYPE_EXTEND_H = 3;
public float clipByParentRectTop;
public float clipByParentRectBottom;
public float clipByParentRectLeft;
public float clipByParentRectRight;
public Rect imageViewEntireRect;
public Rect imageViewVisibleRect;
public Rect scaledBitmapRect;
public int type = -1;
public boolean isTotalVisible;
public boolean isTotalInvisible;
public boolean isScreenPortrait;
public float thumbnailWidthHeightRatio;
public int thumbnailWidth;
public int thumbnailHeight;
public int widgetWidth;
public int widgetHeight;
public static AnimationRect buildFromImageView(ImageView imageView) {
AnimationRect rect = new AnimationRect();
rect.isScreenPortrait = Utility.isDevicePort();
Drawable drawable = imageView.getDrawable();
Bitmap bitmap = null;
if (drawable instanceof BitmapDrawable) {
bitmap = ((BitmapDrawable) drawable).getBitmap();
}
if (bitmap == null) {
return null;
}
rect.widgetWidth = imageView.getWidth();
rect.widgetHeight = imageView.getHeight();
rect.thumbnailWidthHeightRatio = (float) bitmap.getWidth() / (float) bitmap.getHeight();
rect.thumbnailWidth = bitmap.getWidth();
rect.thumbnailHeight = bitmap.getHeight();
rect.imageViewEntireRect = new Rect();
int[] location = new int[2];
imageView.getLocationOnScreen(location);
rect.imageViewEntireRect.left = location[0];
rect.imageViewEntireRect.top = location[1];
rect.imageViewEntireRect.right = rect.imageViewEntireRect.left + imageView.getWidth();
rect.imageViewEntireRect.bottom = rect.imageViewEntireRect.top + imageView.getHeight();
rect.imageViewVisibleRect = new Rect();
boolean isVisible = imageView.getGlobalVisibleRect(rect.imageViewVisibleRect);
boolean checkWidth = rect.imageViewVisibleRect.width() < imageView.getWidth();
boolean checkHeight = rect.imageViewVisibleRect.height() < imageView.getHeight();
rect.isTotalVisible = isVisible && !checkWidth && !checkHeight;
rect.isTotalInvisible = !isVisible;
ImageView.ScaleType scaledType = imageView.getScaleType();
Rect scaledBitmapRect = new Rect(rect.imageViewEntireRect);
int bitmapWidth = bitmap.getWidth();
int bitmapHeight = bitmap.getHeight();
int imageViewWidth = imageView.getWidth();
int imageViewHeight = imageView.getHeight();
float startScale;
int deltaX;
int deltaY;
switch (scaledType) {
case CENTER_CROP:
if ((float) imageViewWidth / bitmapWidth
> (float) imageViewHeight / bitmapHeight) {
startScale = (float) imageViewWidth / bitmapWidth;
rect.type = TYPE_CLIP_V;
} else {
startScale = (float) imageViewHeight / bitmapHeight;
rect.type = TYPE_CLIP_H;
}
bitmapHeight = (int) (bitmapHeight * startScale);
bitmapWidth = (int) (bitmapWidth * startScale);
deltaX = (imageViewWidth - bitmapWidth) / 2;
deltaY = (imageViewHeight - bitmapHeight) / 2;
scaledBitmapRect.set(scaledBitmapRect.left + deltaX, scaledBitmapRect.top + deltaY,
scaledBitmapRect.right - deltaX,
scaledBitmapRect.bottom - deltaY);
break;
case FIT_CENTER:
if ((float) imageViewWidth / bitmapWidth
> (float) imageViewHeight / bitmapHeight) {
// Extend start bounds horizontally
startScale = (float) imageViewHeight / bitmapHeight;
rect.type = TYPE_EXTEND_V;
} else {
startScale = (float) imageViewWidth / bitmapWidth;
rect.type = TYPE_EXTEND_H;
}
bitmapHeight = (int) (bitmapHeight * startScale);
bitmapWidth = (int) (bitmapWidth * startScale);
deltaX = (imageViewWidth - bitmapWidth) / 2;
deltaY = (imageViewHeight - bitmapHeight) / 2;
scaledBitmapRect
.set(scaledBitmapRect.left + deltaX, scaledBitmapRect.top + deltaY,
scaledBitmapRect.right - deltaX,
scaledBitmapRect.bottom - deltaY);
break;
}
rect.scaledBitmapRect = scaledBitmapRect;
return rect;
}
public static float getClipLeft(AnimationRect animationRect, Rect finalBounds) {
final Rect startBounds = animationRect.scaledBitmapRect;
float startScale;
if ((float) finalBounds.width() / finalBounds.height()
> (float) startBounds.width() / startBounds.height()) {
startScale = (float) startBounds.height() / finalBounds.height();
} else {
startScale = (float) startBounds.width() / finalBounds.width();
}
int oriBitmapScaledWidth = (int) (finalBounds.width() * startScale);
//sina server may cut thumbnail's right or bottom
int thumbnailAndOriDeltaRightSize = Math
.abs(animationRect.scaledBitmapRect.width() - oriBitmapScaledWidth);
float serverClipThumbnailRightSizePercent = (float) thumbnailAndOriDeltaRightSize
/ (float) oriBitmapScaledWidth;
float deltaH = (float) (oriBitmapScaledWidth
- oriBitmapScaledWidth * serverClipThumbnailRightSizePercent
- animationRect.widgetWidth);
float deltaLeft = deltaH / 2;
if (!animationRect.isTotalVisible && !animationRect.isTotalInvisible) {
float deltaInvisibleLeft = Math
.abs(animationRect.imageViewVisibleRect.left
- animationRect.imageViewEntireRect.left);
deltaLeft += deltaInvisibleLeft;
}
return (deltaLeft) / (float) oriBitmapScaledWidth;
}
public static float getClipTop(AnimationRect animationRect, Rect finalBounds) {
final Rect startBounds = animationRect.scaledBitmapRect;
float startScale;
if ((float) finalBounds.width() / finalBounds.height()
> (float) startBounds.width() / startBounds.height()) {
startScale = (float) startBounds.height() / finalBounds.height();
} else {
startScale = (float) startBounds.width() / finalBounds.width();
}
int oriBitmapScaledHeight = (int) (finalBounds.height() * startScale);
//sina server may cut thumbnail's right or bottom
int thumbnailAndOriDeltaBottomSize = Math
.abs(animationRect.scaledBitmapRect.height() - oriBitmapScaledHeight);
float serverClipThumbnailBottomSizePercent = (float) thumbnailAndOriDeltaBottomSize
/ (float) oriBitmapScaledHeight;
float deltaV = (float) (oriBitmapScaledHeight
- oriBitmapScaledHeight * serverClipThumbnailBottomSizePercent
- animationRect.widgetHeight);
float deltaTop = deltaV / 2;
if (!animationRect.isTotalVisible && !animationRect.isTotalInvisible) {
float deltaInvisibleTop = Math
.abs(animationRect.imageViewVisibleRect.top
- animationRect.imageViewEntireRect.top);
deltaTop += deltaInvisibleTop;
}
return (deltaTop) / (float) oriBitmapScaledHeight;
}
public static float getClipRight(AnimationRect animationRect, Rect finalBounds) {
final Rect startBounds = animationRect.scaledBitmapRect;
float startScale;
if ((float) finalBounds.width() / finalBounds.height()
> (float) startBounds.width() / startBounds.height()) {
startScale = (float) startBounds.height() / finalBounds.height();
} else {
startScale = (float) startBounds.width() / finalBounds.width();
}
int oriBitmapScaledWidth = (int) (finalBounds.width() * startScale);
//sina server may cut thumbnail's right or bottom
int thumbnailAndOriDeltaRightSize = Math
.abs(animationRect.scaledBitmapRect.width() - oriBitmapScaledWidth);
float serverClipThumbnailRightSizePercent = (float) thumbnailAndOriDeltaRightSize
/ (float) oriBitmapScaledWidth;
float deltaH = (float) (oriBitmapScaledWidth
- oriBitmapScaledWidth * serverClipThumbnailRightSizePercent
- animationRect.widgetWidth);
float deltaRight = deltaH / 2;
if (!animationRect.isTotalVisible && !animationRect.isTotalInvisible) {
float deltaInvisibleRight = Math
.abs(animationRect.imageViewVisibleRect.right
- animationRect.imageViewEntireRect.right);
deltaRight += deltaInvisibleRight;
}
deltaRight += thumbnailAndOriDeltaRightSize;
return (deltaRight) / (float) oriBitmapScaledWidth;
}
public static float getClipBottom(AnimationRect animationRect, Rect finalBounds) {
final Rect startBounds = animationRect.scaledBitmapRect;
float startScale;
if ((float) finalBounds.width() / finalBounds.height()
> (float) startBounds.width() / startBounds.height()) {
startScale = (float) startBounds.height() / finalBounds.height();
} else {
startScale = (float) startBounds.width() / finalBounds.width();
}
int oriBitmapScaledHeight = (int) (finalBounds.height() * startScale);
//sina server may cut thumbnail's right or bottom
int thumbnailAndOriDeltaBottomSize = Math
.abs(animationRect.scaledBitmapRect.height() - oriBitmapScaledHeight);
float serverClipThumbnailBottomSizePercent = (float) thumbnailAndOriDeltaBottomSize
/ (float) oriBitmapScaledHeight;
float deltaV = (float) (oriBitmapScaledHeight
- oriBitmapScaledHeight * serverClipThumbnailBottomSizePercent
- animationRect.widgetHeight);
float deltaBottom = deltaV / 2;
if (!animationRect.isTotalVisible && !animationRect.isTotalInvisible) {
float deltaInvisibleBottom = Math
.abs(animationRect.imageViewVisibleRect.bottom
- animationRect.imageViewEntireRect.bottom);
deltaBottom += deltaInvisibleBottom;
}
deltaBottom += thumbnailAndOriDeltaBottomSize;
return (deltaBottom) / (float) oriBitmapScaledHeight;
}
}