下面列出了android.graphics.Rect#height ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* A factory method to build the appropriate LuminanceSource object based on the format
* of the preview buffers, as described by Camera.Parameters.
*
* @param data A preview frame.
* @param width The width of the image.
* @param height The height of the image.
* @return A PlanarYUVLuminanceSource instance.
*/
public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) {
Rect rect = getFramingRectInPreview();
int previewFormat = configManager.getPreviewFormat();
String previewFormatString = configManager.getPreviewFormatString();
switch (previewFormat) {
// This is the standard Android format which all devices are REQUIRED to support.
// In theory, it's the only one we should ever care about.
case ImageFormat.NV21:
// This format has never been seen in the wild, but is compatible as we only care
// about the Y channel, so allow it.
case ImageFormat.NV16:
return new PlanarYUVLuminanceSource(data, width, height, rect.left, rect.top,
rect.width(), rect.height());
default:
// The Samsung Moment incorrectly uses this variant instead of the 'sp' version.
// Fortunately, it too has all the Y data up front, so we can read it.
if ("yuv420p".equals(previewFormatString)) {
return new PlanarYUVLuminanceSource(data, width, height, rect.left, rect.top,
rect.width(), rect.height());
}
}
throw new IllegalArgumentException("Unsupported picture format: " +
previewFormat + '/' + previewFormatString);
}
/**
* dataList will be reset when called is method.
* @param bottomStringList The String ArrayList in the bottom.
*/
public void setBottomTextList(ArrayList<String> bottomStringList){
// this.dataList = null;
this.bottomTextList = bottomStringList;
Rect r = new Rect();
bottomTextDescent = 0;
barWidth = MINI_BAR_WIDTH;
for(String s:bottomTextList){
textPaint.getTextBounds(s,0,s.length(),r);
if(bottomTextHeight<r.height()){
bottomTextHeight = r.height();
}
if(autoSetWidth&&(barWidth<r.width())){
barWidth = r.width();
}
if(bottomTextDescent<(Math.abs(r.bottom))){
bottomTextDescent = Math.abs(r.bottom);
}
}
setMinimumWidth(2);
postInvalidate();
}
/**
* Writes an array of GIFFrame as an animated GIF
*
* @param frames an array of GIFFrame
* @param os OutputStream for the animated GIF
* @throws Exception
*/
public void writeAnimatedGIF(GIFFrame[] frames, OutputStream os) throws Exception {
// Header first
writeHeader(os, true);
Rect logicalScreenSize = getLogicalScreenSize(frames);
logicalScreenWidth = logicalScreenSize.width();
logicalScreenHeight = logicalScreenSize.height();
// We are going to write animated GIF, so enable animated flag
animated = true;
for(int i = 0; i < frames.length; i++) {
// Retrieve image dimension
int imageWidth = frames[i].getFrameWidth();
int imageHeight = frames[i].getFrameHeight();
int[] pixels = new int[imageWidth * imageHeight];
frames[i].getFrame().getPixels(pixels, 0, imageWidth, 0, 0, imageWidth, imageHeight);
if(frames[i].getTransparencyFlag() == GIFFrame.TRANSPARENCY_INDEX_SET && frames[i].getTransparentColor() != -1) {
int transColor = (frames[i].getTransparentColor() & 0x00ffffff);
for(int j = pixels.length - 1; j > 0; j--) {
int pixel = (pixels[j] & 0x00ffffff);
if(pixel == transColor) pixels[j] = pixel;
}
}
writeFrame(pixels, imageWidth, imageHeight, frames[i].getLeftPosition(), frames[i].getTopPosition(),
frames[i].getDelay(), frames[i].getDisposalMethod(), frames[i].getUserInputFlag(), os);
}
os.write(IMAGE_TRAILER);
os.close();
}
public GraphStyle build() {
float density = context.getResources().getDisplayMetrics().density;
Rect rect = new Rect();
Paint namePaint = new Paint();
Paint amountPaint = new Paint();
Paint linePaint = new Paint();
namePaint.setColor(Color.WHITE);
namePaint.setAntiAlias(true);
namePaint.setTextAlign(Align.LEFT);
namePaint.setTextSize(spToPx(nameTextSize, density));
namePaint.setTypeface(Typeface.DEFAULT_BOLD);
namePaint.getTextBounds("A", 0, 1, rect);
int nameHeight = rect.height();
amountPaint.setColor(Color.WHITE);
amountPaint.setAntiAlias(true);
amountPaint.setTextSize(spToPx(amountTextSize, density));
amountPaint.setTextAlign(Align.CENTER);
amountPaint.getTextBounds("8", 0, 1, rect);
int amountHeight = rect.height();
linePaint.setStyle(Style.FILL);
return new GraphStyle(
spToPx(dy, density),
spToPx(textDy, density),
spToPx(indent, density),
spToPx(lineHeight, density),
nameHeight,
amountHeight,
namePaint,
amountPaint,
linePaint);
}
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 = 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;
}
@Override public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) {
super.drawBitmap(overlayPixels(bitmap), src, dst, paint);
if (overlayRatioEnabled) {
float srcWidth = src != null ? src.width() : bitmap.getWidth();
float srcHeight = src != null ? src.height() : bitmap.getHeight();
float dstWidth = dst != null ? dst.width() : bitmap.getWidth();
float dstHeight = dst != null ? dst.height() : bitmap.getHeight();
int offsetX = dst != null ? dst.left : 0;
int offsetY = dst != null ? dst.top : 0;
drawScaleValue(bitmap, dstWidth / srcWidth, dstHeight / srcHeight, offsetX, offsetY);
}
}
public CustomTabObserver(
Application application, CustomTabsSessionToken session, boolean openedByChrome) {
if (openedByChrome) {
mCustomTabsConnection = null;
} else {
mCustomTabsConnection = CustomTabsConnection.getInstance(application);
}
mSession = session;
if (!openedByChrome && mCustomTabsConnection.shouldSendNavigationInfoForSession(mSession)) {
float desiredWidth = application.getResources().getDimensionPixelSize(
R.dimen.custom_tabs_screenshot_width);
float desiredHeight = application.getResources().getDimensionPixelSize(
R.dimen.custom_tabs_screenshot_height);
Rect bounds = ExternalPrerenderHandler.estimateContentSize(application, false);
if (bounds.width() == 0 || bounds.height() == 0) {
mContentBitmapWidth = (int) Math.round(desiredWidth);
mContentBitmapHeight = (int) Math.round(desiredHeight);
} else {
// Compute a size that scales the content bitmap to fit one (or both) dimensions,
// but also preserves aspect ratio.
float scale =
Math.min(desiredWidth / bounds.width(), desiredHeight / bounds.height());
mContentBitmapWidth = (int) Math.round(bounds.width() * scale);
mContentBitmapHeight = (int) Math.round(bounds.height() * scale);
}
}
mOpenedByChrome = openedByChrome;
resetPageLoadTracking();
}
/**
* 获取除了顶部状态栏的屏幕高度
*
* @param activity
* @return
*/
public static int getActualScreenHeight(Activity activity) {
Rect frame = new Rect();
Window win = activity.getWindow();
win.getDecorView().getWindowVisibleDisplayFrame(frame);
return frame.height();
}
protected void onTouchCancel(float x, float y) {
if (mState.mEffect != null) {
final Rect r = getBounds();
if (x > r.right) x = r.width();
else x = x - r.left;
if (y > r.bottom) y = r.height();
else y = y - r.top;
mState.mEffect.touchCancel(x, y);
// Cancel
cancelAnim();
}
}
/**
* Fix the given rectangle if it doesn't confirm to aspect ration rule.<br>
* Make sure that width and height are equal if 1:1 fixed aspect ratio is requested.
*/
private static void fixRectForAspectRatio(Rect rect, int aspectRatioX, int aspectRatioY) {
if (aspectRatioX == aspectRatioY && rect.width() != rect.height()) {
if (rect.height() > rect.width()) {
rect.bottom -= rect.height() - rect.width();
} else {
rect.right -= rect.width() - rect.height();
}
}
}
private float[] pointToSatVal(float x, float y){
final Rect rect = mSatValRect;
float[] result = new float[2];
float width = rect.width();
float height = rect.height();
if (x < rect.left){
x = 0f;
}
else if(x > rect.right){
x = width;
}
else{
x = x - rect.left;
}
if (y < rect.top){
y = 0f;
}
else if(y > rect.bottom){
y = height;
}
else{
y = y - rect.top;
}
result[0] = 1.f / width * x;
result[1] = 1.f - (1.f / height * y);
return result;
}
/**
* Outputs the bounds a stack should be given the presence of a docked stack on the display.
* @param displayRect The bounds of the display the docked stack is on.
* @param outBounds Output bounds that should be used for the stack.
* @param dockedBounds Bounds of the docked stack.
* @param dockDividerWidth We need to know the width of the divider make to the output bounds
* close to the side of the dock.
* @param dockOnTopOrLeft If the docked stack is on the top or left side of the screen.
*/
private void getStackDockedModeBounds(
Rect displayRect, Rect outBounds, Rect dockedBounds, int dockDividerWidth,
boolean dockOnTopOrLeft) {
final boolean dockedStack = inSplitScreenPrimaryWindowingMode();
final boolean splitHorizontally = displayRect.width() > displayRect.height();
outBounds.set(displayRect);
if (dockedStack) {
if (mService.mDockedStackCreateBounds != null) {
outBounds.set(mService.mDockedStackCreateBounds);
return;
}
// The initial bounds of the docked stack when it is created about half the screen space
// and its bounds can be adjusted after that. The bounds of all other stacks are
// adjusted to occupy whatever screen space the docked stack isn't occupying.
final DisplayInfo di = mDisplayContent.getDisplayInfo();
mService.mPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight,
di.displayCutout, mTmpRect2);
final int position = new DividerSnapAlgorithm(mService.mContext.getResources(),
di.logicalWidth,
di.logicalHeight,
dockDividerWidth,
mDisplayContent.getConfiguration().orientation == ORIENTATION_PORTRAIT,
mTmpRect2).getMiddleTarget().position;
if (dockOnTopOrLeft) {
if (splitHorizontally) {
outBounds.right = position;
} else {
outBounds.bottom = position;
}
} else {
if (splitHorizontally) {
outBounds.left = position + dockDividerWidth;
} else {
outBounds.top = position + dockDividerWidth;
}
}
return;
}
// Other stacks occupy whatever space is left by the docked stack.
if (!dockOnTopOrLeft) {
if (splitHorizontally) {
outBounds.right = dockedBounds.left - dockDividerWidth;
} else {
outBounds.bottom = dockedBounds.top - dockDividerWidth;
}
} else {
if (splitHorizontally) {
outBounds.left = dockedBounds.right + dockDividerWidth;
} else {
outBounds.top = dockedBounds.bottom + dockDividerWidth;
}
}
DockedDividerUtils.sanitizeStackBounds(outBounds, !dockOnTopOrLeft);
}
private void drawBackground() {
Rect rect = new Rect((int) mBackgroundPaddingRect.left + mAnchorWidth,
(int) mBackgroundPaddingRect.top,
(int) (getWidth() - mBackgroundPaddingRect.right - mAnchorWidth),
(int) (getHeight() - mBackgroundPaddingRect.bottom));
mBackgroundDrawable.setBounds(rect);
mAbsoluteY = (int) (mBackgroundPaddingRect.top - mBackgroundPaddingRect.bottom);
Log.d(TAG, "mAbsoluteY:" + mBackgroundPaddingRect.top + " : " + mBackgroundPaddingRect.bottom + " : " + (mBackgroundPaddingRect.top - mBackgroundPaddingRect.bottom));
mCurrentX = mPivotX = getWidth() / 2;
mCurrentY = mPivotY = getHeight() / 2;
int widthBase = rect.width() / getCount();
int widthHalf = widthBase / 2;
int heightBase = rect.height() / getCount();
int heightHalf = heightBase / 2;
mAnchor = new int[getCount()][2];
for (int i = 0, j = 1; i < getCount(); i++, j++) {
// if (mType == 1) {
if (i == 0) {
mAnchor[i][0] = mModIsHorizontal ? rect.left : mPivotX;
} else if (i == getCount() - 1) {
mAnchor[i][0] = mModIsHorizontal ? rect.right : mPivotX;
} else {
mAnchor[i][0] = mModIsHorizontal ? widthBase * j - widthHalf + rect.left : mPivotX;
}
mAnchor[i][1] = !mModIsHorizontal ? heightBase * j - heightHalf + rect.top : mPivotY + mAbsoluteY / 2;
// }
}
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setTextSize(mTextSize);
mPaint.setColor(mTextColor);
mPaint.setTextAlign(Paint.Align.CENTER);
}
/**
* 画面がフルスクリーンになった場合はViewを非表示にします。
*/
@Override
public void onScreenChanged(Rect windowRect, int visibility) {
// detect status bar
final boolean isFitSystemWindowTop = windowRect.top == 0;
boolean isHideStatusBar;
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1 && visibility != FullscreenObserverView.NO_LAST_VISIBILITY) {
// Support for screen rotation when setSystemUiVisibility is used
isHideStatusBar = isFitSystemWindowTop || (visibility & View.SYSTEM_UI_FLAG_LOW_PROFILE) == View.SYSTEM_UI_FLAG_LOW_PROFILE;
} else {
isHideStatusBar = isFitSystemWindowTop;
}
// detect navigation bar
final boolean isHideNavigationBar;
if (visibility == FullscreenObserverView.NO_LAST_VISIBILITY) {
// At the first it can not get the correct value, so do special processing
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
mWindowManager.getDefaultDisplay().getRealMetrics(mDisplayMetrics);
isHideNavigationBar = windowRect.width() - mDisplayMetrics.widthPixels == 0 && windowRect.bottom - mDisplayMetrics.heightPixels == 0;
} else {
mWindowManager.getDefaultDisplay().getMetrics(mDisplayMetrics);
isHideNavigationBar = windowRect.width() - mDisplayMetrics.widthPixels > 0 || windowRect.height() - mDisplayMetrics.heightPixels > 0;
}
} else {
isHideNavigationBar = (visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
}
final boolean isPortrait = mResources.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
// update FloatingView layout
mTargetFloatingView.onUpdateSystemLayout(isHideStatusBar, isHideNavigationBar, isPortrait, windowRect);
// フルスクリーンでの非表示モードでない場合は何もしない
if (mDisplayMode != DISPLAY_MODE_HIDE_FULLSCREEN) {
return;
}
mIsMoveAccept = false;
final int state = mTargetFloatingView.getState();
// 重なっていない場合は全て非表示処理
if (state == FloatingView.STATE_NORMAL) {
final int size = mFloatingViewList.size();
for (int i = 0; i < size; i++) {
final FloatingView floatingView = mFloatingViewList.get(i);
floatingView.setVisibility(isFitSystemWindowTop ? View.GONE : View.VISIBLE);
}
mTrashView.dismiss();
}
// 重なっている場合は削除
else if (state == FloatingView.STATE_INTERSECTING) {
mTargetFloatingView.setFinishing();
mTrashView.dismiss();
}
}
private static MotionEvent.PointerCoords extractElementCoordinates(
final String actionId, final W3CGestureModel gesture, final Object originValue) {
String elementId = null;
if (originValue instanceof String) {
elementId = (String) originValue;
} else if (originValue instanceof Map) {
// It's how this is defined in WebDriver source:
//
// if isinstance(origin, WebElement):
// action["origin"] = {"element-6066-11e4-a52e-4f735466cecf": origin.id}
//noinspection unchecked
elementId = new ElementModel((Map<String, Object>) originValue).getUnifiedId();
}
if (elementId == null) {
throw new ActionsParseException(String.format(
"An unknown element '%s' is set for action item '%s' of action '%s'",
originValue, gesture, actionId));
}
final MotionEvent.PointerCoords result = new MotionEvent.PointerCoords();
Rect bounds;
Session session = AppiumUIA2Driver.getInstance().getSessionOrThrow();
try {
final AndroidElement element = session.getKnownElements().getElementFromCache(elementId);
//noinspection ConstantConditions
bounds = element.getBounds();
if (bounds.width() == 0 || bounds.height() == 0) {
throw new ActionsParseException(String.format(
"The element with id '%s' has zero width/height in the action item '%s' of action '%s'",
elementId, gesture, actionId));
}
} catch (NullPointerException | UiObjectNotFoundException e) {
throw new ActionsParseException(String.format(
"An unknown element id '%s' is set for the action item '%s' of action '%s'",
elementId, gesture, actionId));
}
// https://w3c.github.io/webdriver/webdriver-spec.html#pointer-actions
// > Let x element and y element be the result of calculating the in-view center point of element.
result.x = bounds.left + bounds.width() / 2.0f;
result.y = bounds.top + bounds.height() / 2.0f;
if (gesture.x != null) {
result.x += gesture.x.floatValue();
// TODO: Shall we throw an exception if result.x is outside of bounds rect?
}
if (gesture.y != null) {
result.y += gesture.y.floatValue();
// TODO: Shall we throw an exception if result.y is outside of bounds rect?
}
return result;
}
private void drawWithNewAspectRatio(Canvas canvas) {
if (compositionLayer == null) {
return;
}
int saveCount = -1;
Rect bounds = getBounds();
// In fitXY mode, the scale doesn't take effect.
float scaleX = bounds.width() / (float) composition.getBounds().width();
float scaleY = bounds.height() / (float) composition.getBounds().height();
if (isExtraScaleEnabled) {
float maxScale = Math.min(scaleX, scaleY);
float extraScale = 1f;
if (maxScale < 1f) {
extraScale = extraScale / maxScale;
scaleX = scaleX / extraScale;
scaleY = scaleY / extraScale;
}
if (extraScale > 1) {
saveCount = canvas.save();
float halfWidth = bounds.width() / 2f;
float halfHeight = bounds.height() / 2f;
float scaledHalfWidth = halfWidth * maxScale;
float scaledHalfHeight = halfHeight * maxScale;
canvas.translate(
halfWidth - scaledHalfWidth,
halfHeight - scaledHalfHeight);
canvas.scale(extraScale, extraScale, scaledHalfWidth, scaledHalfHeight);
}
}
matrix.reset();
matrix.preScale(scaleX, scaleY);
compositionLayer.draw(canvas, matrix, alpha);
if (saveCount > 0) {
canvas.restoreToCount(saveCount);
}
}
/**
* Crop image bitmap from URI by decoding it with specific width and height to down-sample if required.
*
* @param orgWidth used to get rectangle from points (handle edge cases to limit rectangle)
* @param orgHeight used to get rectangle from points (handle edge cases to limit rectangle)
* @param sampleMulti used to increase the sampling of the image to handle memory issues.
*/
private static BitmapSampled cropBitmap(Context context, Uri loadedImageUri, float[] points, int degreesRotated, int orgWidth, int orgHeight, boolean fixAspectRatio, int aspectRatioX, int aspectRatioY, int reqWidth, int reqHeight, int sampleMulti) {
// get the rectangle in original image that contains the required cropped area (larger for non rectangular crop)
Rect rect = getRectFromPoints(points, orgWidth, orgHeight, fixAspectRatio, aspectRatioX, aspectRatioY);
int width = reqWidth > 0 ? reqWidth : rect.width();
int height = reqHeight > 0 ? reqHeight : rect.height();
Bitmap result = null;
int sampleSize = 1;
try {
// decode only the required image from URI, optionally sub-sampling if reqWidth/reqHeight is given.
BitmapSampled bitmapSampled = decodeSampledBitmapRegion(context, loadedImageUri, rect, width, height, sampleMulti);
result = bitmapSampled.bitmap;
sampleSize = bitmapSampled.sampleSize;
} catch (Exception ignored) {
}
if (result != null) {
try {
// rotate the decoded region by the required amount
result = rotateBitmapInt(result, degreesRotated);
// rotating by 0, 90, 180 or 270 degrees doesn't require extra cropping
if (degreesRotated % 90 != 0) {
// extra crop because non rectangular crop cannot be done directly on the image without rotating first
result = cropForRotatedImage(result, points, rect, degreesRotated, fixAspectRatio, aspectRatioX, aspectRatioY);
}
} catch (OutOfMemoryError e) {
if (result != null) {
result.recycle();
}
throw e;
}
return new BitmapSampled(result, sampleSize);
} else {
// failed to decode region, may be skia issue, try full decode and then crop
return cropBitmap(context, loadedImageUri, points, degreesRotated, fixAspectRatio, aspectRatioX, aspectRatioY, sampleMulti, rect, width, height);
}
}
/**
* Gets the crop window's position relative to the source Bitmap (not the image
* displayed in the CropImageView).
*
* @return a RectF instance containing cropped area boundaries of the source Bitmap
*/
public RectF getActualCropRect() {
final Rect displayedImageRect = ImageViewUtil.getBitmapRectCenterInside(mBitmap, mImageView);
// Get the scale factor between the actual Bitmap dimensions and the
// displayed dimensions for width.
final float actualImageWidth = mBitmap.getWidth();
final float displayedImageWidth = displayedImageRect.width();
final float scaleFactorWidth = actualImageWidth / displayedImageWidth;
// Get the scale factor between the actual Bitmap dimensions and the
// displayed dimensions for height.
final float actualImageHeight = mBitmap.getHeight();
final float displayedImageHeight = displayedImageRect.height();
final float scaleFactorHeight = actualImageHeight / displayedImageHeight;
// Get crop window position relative to the displayed image.
final float displayedCropLeft = Edge.LEFT.getCoordinate() - displayedImageRect.left;
final float displayedCropTop = Edge.TOP.getCoordinate() - displayedImageRect.top;
final float displayedCropWidth = Edge.getWidth();
final float displayedCropHeight = Edge.getHeight();
// Scale the crop window position to the actual size of the Bitmap.
float actualCropLeft = displayedCropLeft * scaleFactorWidth;
float actualCropTop = displayedCropTop * scaleFactorHeight;
float actualCropRight = actualCropLeft + displayedCropWidth * scaleFactorWidth;
float actualCropBottom = actualCropTop + displayedCropHeight * scaleFactorHeight;
// Correct for floating point errors. Crop rect boundaries should not
// exceed the source Bitmap bounds.
actualCropLeft = Math.max(0f, actualCropLeft);
actualCropTop = Math.max(0f, actualCropTop);
actualCropRight = Math.min(mBitmap.getWidth(), actualCropRight);
actualCropBottom = Math.min(mBitmap.getHeight(), actualCropBottom);
final RectF actualCropRect = new RectF(actualCropLeft,
actualCropTop,
actualCropRight,
actualCropBottom);
return actualCropRect;
}
/**
* Set the initial crop window size and position. This is dependent on the
* size and position of the image being cropped.
*
* @param bitmapRect the bounding box around the image being cropped
*/
private void initCropWindow(Rect bitmapRect) {
// Tells the attribute functions the crop window has already been
// initialized
if (initializedCropWindow == false)
initializedCropWindow = true;
if (mFixAspectRatio) {
// If the image aspect ratio is wider than the crop aspect ratio,
// then the image height is the determining initial length. Else,
// vice-versa.
if (AspectRatioUtil.calculateAspectRatio(bitmapRect) > mTargetAspectRatio) {
Edge.TOP.setCoordinate(bitmapRect.top);
Edge.BOTTOM.setCoordinate(bitmapRect.bottom);
final float centerX = getWidth() / 2f;
// Limits the aspect ratio to no less than 40 wide or 40 tall
final float cropWidth = Math.max(Edge.MIN_CROP_LENGTH_PX,
AspectRatioUtil.calculateWidth(Edge.TOP.getCoordinate(),
Edge.BOTTOM.getCoordinate(),
mTargetAspectRatio));
// Create new TargetAspectRatio if the original one does not fit
// the screen
if (cropWidth == Edge.MIN_CROP_LENGTH_PX)
mTargetAspectRatio = (Edge.MIN_CROP_LENGTH_PX) / (Edge.BOTTOM.getCoordinate() - Edge.TOP.getCoordinate());
final float halfCropWidth = cropWidth / 2f;
Edge.LEFT.setCoordinate(centerX - halfCropWidth);
Edge.RIGHT.setCoordinate(centerX + halfCropWidth);
} else {
Edge.LEFT.setCoordinate(bitmapRect.left);
Edge.RIGHT.setCoordinate(bitmapRect.right);
final float centerY = getHeight() / 2f;
// Limits the aspect ratio to no less than 40 wide or 40 tall
final float cropHeight = Math.max(Edge.MIN_CROP_LENGTH_PX,
AspectRatioUtil.calculateHeight(Edge.LEFT.getCoordinate(),
Edge.RIGHT.getCoordinate(),
mTargetAspectRatio));
// Create new TargetAspectRatio if the original one does not fit
// the screen
if (cropHeight == Edge.MIN_CROP_LENGTH_PX)
mTargetAspectRatio = (Edge.RIGHT.getCoordinate() - Edge.LEFT.getCoordinate()) / Edge.MIN_CROP_LENGTH_PX;
final float halfCropHeight = cropHeight / 2f;
Edge.TOP.setCoordinate(centerY - halfCropHeight);
Edge.BOTTOM.setCoordinate(centerY + halfCropHeight);
}
} else { // ... do not fix aspect ratio...
// Initialize crop window to have 10% padding w/ respect to image.
final float horizontalPadding = 0.1f * bitmapRect.width();
final float verticalPadding = 0.1f * bitmapRect.height();
Edge.LEFT.setCoordinate(bitmapRect.left + horizontalPadding);
Edge.TOP.setCoordinate(bitmapRect.top + verticalPadding);
Edge.RIGHT.setCoordinate(bitmapRect.right - horizontalPadding);
Edge.BOTTOM.setCoordinate(bitmapRect.bottom - verticalPadding);
}
}
private void remountComponentHostToRootIfNeeded(int index) {
final ComponentHost rootHost = mHostsByMarker.get(ROOT_HOST_ID);
final MountItem item = getItemAt(index);
final ComponentHost host = (ComponentHost) item.getHost();
if (host == rootHost) {
// Already mounted to the root
return;
}
final Object content = item.getContent();
// Before unmounting item get its position inside the root
int left = 0;
int top = 0;
int right;
int bottom;
// Get left/top position of the item's host first
ComponentHost componentHost = (ComponentHost) item.getHost();
while (componentHost != rootHost) {
left += componentHost.getLeft();
top += componentHost.getTop();
componentHost = (ComponentHost) componentHost.getParent();
}
if (content instanceof View) {
final View view = (View) content;
left += view.getLeft();
top += view.getTop();
right = left + view.getWidth();
bottom = top + view.getHeight();
} else {
final Rect bounds = ((Drawable) content).getBounds();
left += bounds.left;
right = left + bounds.width();
top += bounds.top;
bottom = top + bounds.height();
}
final LayoutOutput output = getLayoutOutput(item);
// Unmount from the current host
unmount(host, index, content, item, output);
// Apply new bounds to the content as it will be mounted in the root now
applyBoundsToMountContent(content, left, top, right, bottom, false);
// Mount to the root
mount(rootHost, index, content, item, output);
// Set new host to the MountItem
item.setHost(rootHost);
}