下面列出了android.graphics.Rect#offset ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Converts a rectangle within the view to the corresponding rectangle from the source file, taking
* into account the current scale, translation, orientation and clipped region. This can be used
* to decode a bitmap from the source file.
* <p>
* This method will only work when the image has fully initialised, after {@link #isReady()} returns
* true. It is not guaranteed to work with preloaded bitmaps.
* <p>
* The result is written to the fRect argument. Re-use a single instance for efficiency.
*
* @param vRect rectangle representing the view area to interpret.
* @param fRect rectangle instance to which the result will be written. Re-use for efficiency.
*/
public void viewToFileRect(Rect vRect, Rect fRect) {
if (vTranslate == null || !readySent) {
return;
}
fRect.set(
(int) viewToSourceX(vRect.left),
(int) viewToSourceY(vRect.top),
(int) viewToSourceX(vRect.right),
(int) viewToSourceY(vRect.bottom));
fileSRect(fRect, fRect);
fRect.set(
Math.max(0, fRect.left),
Math.max(0, fRect.top),
Math.min(sWidth, fRect.right),
Math.min(sHeight, fRect.bottom)
);
if (sRegion != null) {
fRect.offset(sRegion.left, sRegion.top);
}
}
/**
* Converts a rectangle within the view to the corresponding rectangle from the source file, taking
* into account the current scale, translation, orientation and clipped region. This can be used
* to decode a bitmap from the source file.
* <p>
* This method will only work when the image has fully initialised, after {@link #isReady()} returns
* true. It is not guaranteed to work with preloaded bitmaps.
* <p>
* The result is written to the fRect argument. Re-use a single instance for efficiency.
*
* @param vRect rectangle representing the view area to interpret.
* @param fRect rectangle instance to which the result will be written. Re-use for efficiency.
*/
public void viewToFileRect(Rect vRect, Rect fRect) {
if (vTranslate == null || !readySent) {
return;
}
fRect.set(
(int) viewToSourceX(vRect.left),
(int) viewToSourceY(vRect.top),
(int) viewToSourceX(vRect.right),
(int) viewToSourceY(vRect.bottom));
fileSRect(fRect, fRect);
fRect.set(
Math.max(0, fRect.left),
Math.max(0, fRect.top),
Math.min(sWidth, fRect.right),
Math.min(sHeight, fRect.bottom)
);
if (sRegion != null) {
fRect.offset(sRegion.left, sRegion.top);
}
}
/** This returns the coordinates of an app in a given cell, relative to the DragLayer */
Rect getCellCoordinates(int cellX, int cellY) {
Rect coords = new Rect();
mContent.cellToRect(cellX, cellY, 1, 1, coords);
int[] hotseatInParent = new int[2];
Utilities.getDescendantCoordRelativeToParent(this, mLauncher.getDragLayer(),
hotseatInParent, false);
coords.offset(hotseatInParent[0], hotseatInParent[1]);
// Center the icon
int cWidth = mContent.getShortcutsAndWidgets().getCellContentWidth();
int cHeight = mContent.getShortcutsAndWidgets().getCellContentHeight();
int cellPaddingX = (int) Math.max(0, ((coords.width() - cWidth) / 2f));
int cellPaddingY = (int) Math.max(0, ((coords.height() - cHeight) / 2f));
coords.offset(cellPaddingX, cellPaddingY);
return coords;
}
/**
* Converts a rectangle within the view to the corresponding rectangle from the source file, taking
* into account the current scale, translation, orientation and clipped region. This can be used
* to decode a bitmap from the source file.
*
* This method will only work when the image has fully initialised, after {@link #isReady()} returns
* true. It is not guaranteed to work with preloaded bitmaps.
*
* The result is written to the fRect argument. Re-use a single instance for efficiency.
* @param vRect rectangle representing the view area to interpret.
* @param fRect rectangle instance to which the result will be written. Re-use for efficiency.
*/
public void viewToFileRect(Rect vRect, Rect fRect) {
if (vTranslate == null || !readySent) {
return;
}
fRect.set(
(int)viewToSourceX(vRect.left),
(int)viewToSourceY(vRect.top),
(int)viewToSourceX(vRect.right),
(int)viewToSourceY(vRect.bottom));
fileSRect(fRect, fRect);
fRect.set(
Math.max(0, fRect.left),
Math.max(0, fRect.top),
Math.min(sWidth, fRect.right),
Math.min(sHeight, fRect.bottom)
);
if (sRegion != null) {
fRect.offset(sRegion.left, sRegion.top);
}
}
/**
* Converts a rectangle within the view to the corresponding rectangle from the source file, taking
* into account the current scale, translation, orientation and clipped region. This can be used
* to decode a bitmap from the source file.
* <p>
* This method will only work when the image has fully initialised, after {@link #isReady()} returns
* true. It is not guaranteed to work with preloaded bitmaps.
* <p>
* The result is written to the fRect argument. Re-use a single instance for efficiency.
*
* @param vRect rectangle representing the view area to interpret.
* @param fRect rectangle instance to which the result will be written. Re-use for efficiency.
*/
public void viewToFileRect(Rect vRect, Rect fRect) {
if (vTranslate == null || !readySent) {
return;
}
fRect.set(
(int) viewToSourceX(vRect.left),
(int) viewToSourceY(vRect.top),
(int) viewToSourceX(vRect.right),
(int) viewToSourceY(vRect.bottom));
fileSRect(fRect, fRect);
fRect.set(
Math.max(0, fRect.left),
Math.max(0, fRect.top),
Math.min(sWidth, fRect.right),
Math.min(sHeight, fRect.bottom)
);
if (sRegion != null) {
fRect.offset(sRegion.left, sRegion.top);
}
}
private AccessibilityNodeInfo createAccessibiltyNodeInfoForInputText(
int left, int top, int right, int bottom) {
AccessibilityNodeInfo info = mInputText.createAccessibilityNodeInfo();
info.setSource(NumberPicker.this, VIRTUAL_VIEW_ID_INPUT);
if (mAccessibilityFocusedView != VIRTUAL_VIEW_ID_INPUT) {
info.addAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
}
if (mAccessibilityFocusedView == VIRTUAL_VIEW_ID_INPUT) {
info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS);
}
Rect boundsInParent = mTempRect;
boundsInParent.set(left, top, right, bottom);
info.setVisibleToUser(isVisibleToUser(boundsInParent));
info.setBoundsInParent(boundsInParent);
Rect boundsInScreen = boundsInParent;
int[] locationOnScreen = mTempArray;
getLocationOnScreen(locationOnScreen);
boundsInScreen.offset(locationOnScreen[0], locationOnScreen[1]);
info.setBoundsInScreen(boundsInScreen);
return info;
}
private AccessibilityNodeInfo createAccessibiltyNodeInfoForInputText(
int left, int top, int right, int bottom) {
AccessibilityNodeInfo info = mInputText.createAccessibilityNodeInfo();
info.setSource(NumberPicker.this, VIRTUAL_VIEW_ID_INPUT);
if (mAccessibilityFocusedView != VIRTUAL_VIEW_ID_INPUT) {
info.addAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
}
if (mAccessibilityFocusedView == VIRTUAL_VIEW_ID_INPUT) {
info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS);
}
Rect boundsInParent = mTempRect;
boundsInParent.set(left, top, right, bottom);
// info.setVisibleToUser(isVisibleToUser(boundsInParent));
info.setBoundsInParent(boundsInParent);
Rect boundsInScreen = boundsInParent;
int[] locationOnScreen = mTempArray;
getLocationOnScreen(locationOnScreen);
boundsInScreen.offset(locationOnScreen[0], locationOnScreen[1]);
info.setBoundsInScreen(boundsInScreen);
return info;
}
private void getVisibleRect(View view, Rect rect, boolean fullscreen) {
if (fullscreen) {
view.getGlobalVisibleRect(rect);
return;
}
int[] offset = new int[2];
view.getLocationOnScreen(offset);
view.getLocalVisibleRect(rect);
rect.offset(offset[0], offset[1]);
}
@Override
protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
int closestChildIndex = -1;
if (gainFocus && previouslyFocusedRect != null) {
previouslyFocusedRect.offset(getScrollX(), getScrollY());
// figure out which item should be selected based on previously
// focused rect
Rect otherRect = mTempRect;
int minDistance = Integer.MAX_VALUE;
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
// only consider view's on appropriate edge of grid
if (!mGridBuilder.isCandidateSelection(i, direction)) {
continue;
}
final View other = getChildAt(i);
other.getDrawingRect(otherRect);
offsetDescendantRectToMyCoords(other, otherRect);
int distance = getDistance(previouslyFocusedRect, otherRect, direction);
if (distance < minDistance) {
minDistance = distance;
closestChildIndex = i;
}
}
}
if (closestChildIndex >= 0) {
setSelection(closestChildIndex + mFirstPosition);
} else {
requestLayout();
}
}
private AccessibilityNodeInfo createAccessibilityNodeInfoForVirtualButton(int virtualViewId,
String text, int left, int top, int right, int bottom) {
AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain();
info.setClassName(Button.class.getName());
info.setPackageName(getContext().getPackageName());
info.setSource(NumberPicker.this, virtualViewId);
info.setParent(NumberPicker.this);
info.setText(text);
info.setClickable(true);
info.setLongClickable(true);
info.setEnabled(NumberPicker.this.isEnabled());
Rect boundsInParent = mTempRect;
boundsInParent.set(left, top, right, bottom);
info.setVisibleToUser(getVisibility() == View.VISIBLE);
info.setBoundsInParent(boundsInParent);
Rect boundsInScreen = boundsInParent;
int[] locationOnScreen = mTempArray;
getLocationOnScreen(locationOnScreen);
boundsInScreen.offset(locationOnScreen[0], locationOnScreen[1]);
info.setBoundsInScreen(boundsInScreen);
if (mAccessibilityFocusedView != virtualViewId) {
info.addAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
}
if (mAccessibilityFocusedView == virtualViewId) {
info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS);
}
if (NumberPicker.this.isEnabled()) {
info.addAction(AccessibilityNodeInfo.ACTION_CLICK);
}
return info;
}
private AccessibilityNodeInfo createAccessibilityNodeInfoForVirtualButton(int virtualViewId,
String text, int left, int top, int right, int bottom) {
AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain();
info.setClassName(Button.class.getName());
info.setPackageName(mContext.getPackageName());
info.setSource(NumberPicker.this, virtualViewId);
info.setParent(NumberPicker.this);
info.setText(text);
info.setClickable(true);
info.setLongClickable(true);
info.setEnabled(NumberPicker.this.isEnabled());
Rect boundsInParent = mTempRect;
boundsInParent.set(left, top, right, bottom);
info.setVisibleToUser(isVisibleToUser(boundsInParent));
info.setBoundsInParent(boundsInParent);
Rect boundsInScreen = boundsInParent;
int[] locationOnScreen = mTempArray;
getLocationOnScreen(locationOnScreen);
boundsInScreen.offset(locationOnScreen[0], locationOnScreen[1]);
info.setBoundsInScreen(boundsInScreen);
if (mAccessibilityFocusedView != virtualViewId) {
info.addAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
}
if (mAccessibilityFocusedView == virtualViewId) {
info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS);
}
if (NumberPicker.this.isEnabled()) {
info.addAction(AccessibilityNodeInfo.ACTION_CLICK);
}
return info;
}
static void scaleRectAboutCenter(Rect r, float scale) {
if (scale != 1.0f) {
int cx = r.centerX();
int cy = r.centerY();
r.offset(-cx, -cy);
r.left = (int) (r.left * scale + 0.5f);
r.top = (int) (r.top * scale + 0.5f);
r.right = (int) (r.right * scale + 0.5f);
r.bottom = (int) (r.bottom * scale + 0.5f);
r.offset(cx, cy);
}
}
private Rect getChildViewRect(final View parentView, View childView) {
final Rect childRect = new Rect(childView.getLeft(), childView.getTop(), childView.getRight(), childView.getBottom());
if (parentView == childView) {
return childRect;
}
ViewGroup parent;
while ((parent = (ViewGroup) childView.getParent()) != parentView) {
childRect.offset(parent.getLeft(), parent.getTop());
childView = parent;
}
return childRect;
}
@Override
public Bitmap getTile(int level, int x, int y, Bitmap bitmap) {
int tileSize = getTileSize();
if (bitmap == null) {
bitmap = Bitmap.createBitmap(tileSize, tileSize, Bitmap.Config.ARGB_8888);
}
Canvas c = new Canvas(bitmap);
Rect bounds = new Rect(0, 0, getImageWidth(), getImageHeight());
bounds.offset(-x, -y);
mDrawable.setBounds(bounds);
mDrawable.draw(c);
c.setBitmap(null);
return bitmap;
}
private int getTargetByXY(int x, int y) {
final int position = getPositionByXY(x, y);
if (position < 0) {
return -1;
}
final Rect r = getRectByPosition(position);
final int page = position / mPageSize;
r.inset(r.width() / 4, r.height() / 4);
r.offset(-getWidth() * page, 0);
if (!r.contains(x, y)) {
return -1;
}
return position;
}
@Override
public void drawBitmap(final Bitmap bitmap, final Rect src, final Rect dst,
final SafePaint paint) {
dst.offset(xOffset, yOffset);
getWrappedCanvas().drawBitmap(bitmap, src, dst, paint);
dst.offset(-xOffset, -yOffset);
}
public void updateHq(boolean update) {
Rect viewArea = new Rect(getLeft(),getTop(),getRight(),getBottom());
if (viewArea.width() == mSize.x || viewArea.height() == mSize.y) {
// If the viewArea's size matches the unzoomed size, there is no need for an hq patch
if (mPatch != null) {
mPatch.setImageBitmap(null);
mPatch.invalidate();
}
} else {
final Point patchViewSize = new Point(viewArea.width(), viewArea.height());
final Rect patchArea = new Rect(0, 0, mParentSize.x, mParentSize.y);
// Intersect and test that there is an intersection
if (!patchArea.intersect(viewArea))
return;
// Offset patch area to be relative to the view top left
patchArea.offset(-viewArea.left, -viewArea.top);
boolean area_unchanged = patchArea.equals(mPatchArea) && patchViewSize.equals(mPatchViewSize);
// If being asked for the same area as last time and not because of an update then nothing to do
if (area_unchanged && !update)
return;
boolean completeRedraw = !(area_unchanged && update);
// Stop the drawing of previous patch if still going
if (mDrawPatch != null) {
mDrawPatch.cancel();
mDrawPatch = null;
}
// Create and add the image view if not already done
if (mPatch == null) {
mPatch = new OpaqueImageView(mContext);
mPatch.setScaleType(ImageView.ScaleType.MATRIX);
addView(mPatch);
mSearchView.bringToFront();
}
CancellableTaskDefinition<Void, Void> task;
if (completeRedraw)
task = getDrawPageTask(mPatchBm, patchViewSize.x, patchViewSize.y,
patchArea.left, patchArea.top,
patchArea.width(), patchArea.height());
else
task = getUpdatePageTask(mPatchBm, patchViewSize.x, patchViewSize.y,
patchArea.left, patchArea.top,
patchArea.width(), patchArea.height());
mDrawPatch = new CancellableAsyncTask<Void,Void>(task) {
public void onPostExecute(Void result) {
mPatchViewSize = patchViewSize;
mPatchArea = patchArea;
mPatch.setImageBitmap(mPatchBm);
mPatch.invalidate();
//requestLayout();
// Calling requestLayout here doesn't lead to a later call to layout. No idea
// why, but apparently others have run into the problem.
mPatch.layout(mPatchArea.left, mPatchArea.top, mPatchArea.right, mPatchArea.bottom);
}
};
mDrawPatch.execute();
}
}
/**
* @see {@link #addRect(RectF, Direction)}
*/
public void addRect(Rect rect, Direction dir) {
rect.offset(xOffset, yOffset);
super.addRect(this.toOffsetRectF(rect, sRectF), dir);
rect.offset(-xOffset, -yOffset);
}
/**
* See {@link WebView#requestChildRectangleOnScreen(View, Rect, boolean)}
*/
public boolean requestChildRectangleOnScreen(int childOffsetX, int childOffsetY, Rect rect,
boolean immediate) {
// TODO(mkosiba): WebViewClassic immediately returns false if a zoom animation is
// in progress. We currently can't tell if one is happening.. should we instead cancel any
// scroll animation when the size/pageScaleFactor changes?
// TODO(mkosiba): Take scrollbar width into account in the screenRight/screenBotton
// calculations. http://crbug.com/269032
final int scrollX = mDelegate.getContainerViewScrollX();
final int scrollY = mDelegate.getContainerViewScrollY();
rect.offset(childOffsetX, childOffsetY);
int screenTop = scrollY;
int screenBottom = scrollY + mContainerViewHeight;
int scrollYDelta = 0;
if (rect.bottom > screenBottom) {
int oneThirdOfScreenHeight = mContainerViewHeight / 3;
if (rect.width() > 2 * oneThirdOfScreenHeight) {
// If the rectangle is too tall to fit in the bottom two thirds
// of the screen, place it at the top.
scrollYDelta = rect.top - screenTop;
} else {
// If the rectangle will still fit on screen, we want its
// top to be in the top third of the screen.
scrollYDelta = rect.top - (screenTop + oneThirdOfScreenHeight);
}
} else if (rect.top < screenTop) {
scrollYDelta = rect.top - screenTop;
}
int screenLeft = scrollX;
int screenRight = scrollX + mContainerViewWidth;
int scrollXDelta = 0;
if (rect.right > screenRight && rect.left > screenLeft) {
if (rect.width() > mContainerViewWidth) {
scrollXDelta += (rect.left - screenLeft);
} else {
scrollXDelta += (rect.right - screenRight);
}
} else if (rect.left < screenLeft) {
scrollXDelta -= (screenLeft - rect.left);
}
if (scrollYDelta == 0 && scrollXDelta == 0) {
return false;
}
if (immediate) {
scrollBy(scrollXDelta, scrollYDelta);
return true;
} else {
return animateScrollTo(scrollX + scrollXDelta, scrollY + scrollYDelta);
}
}
private void animateGap(int target) {
for (int i = 0; i < getChildCount(); i++) {
View v = getChildAt(i);
if (i == mLastDragged) {
continue;
}
int newPos = i;
if (mLastDragged < target && i >= mLastDragged + 1 && i <= target) {
newPos--;
} else if (target < mLastDragged && i >= target && i < mLastDragged) {
newPos++;
}
int oldPos = i;
if (newPositions.get(i) != -1) {
oldPos = newPositions.get(i);
}
if (oldPos == newPos) {
continue;
}
// animate
DEBUG_LOG("animateGap from=" + oldPos + ", to=" + newPos);
final Rect oldRect = getRectByPosition(oldPos);
final Rect newRect = getRectByPosition(newPos);
oldRect.offset(-v.getLeft(), -v.getTop());
newRect.offset(-v.getLeft(), -v.getTop());
TranslateAnimation translate = new TranslateAnimation(
oldRect.left, newRect.left,
oldRect.top, newRect.top);
translate.setDuration(ANIMATION_DURATION);
translate.setFillEnabled(true);
translate.setFillAfter(true);
v.clearAnimation();
v.startAnimation(translate);
newPositions.set(i, newPos);
}
}