下面列出了android.graphics.Rect#centerX ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Displays the menuOverlay to the left or or right of the given bounds, depending on which has
* more space.
*
* @param bounds The bounds of the item for which to show the menu
* @return {@code true} if the overlay was drawn to the left given bounds, or {@code false} if the
* overlay was drawn to the right of the given bounds
*/
@VisibleForTesting
boolean placeMenuOverlayLeftOrRightOfBounds(Rect bounds) {
Point screenSize = ScreenUtils.getRealScreenSize(menuOverlay.getContext());
boolean shouldPlaceMenuLeftOfBounds = bounds.centerX() > (screenSize.x / 2);
View fullMenu = menuOverlay.findViewById(R.id.menu_scrim);
int paddingForItem = bounds.width() + PADDING_BETWEEN_ITEM_AND_MENU;
// Ensure the menu is outside the circular cutout for Point Scan.
if (OverlayUtils.areBoundsAPoint(bounds)) {
int distanceFromItemCenterToScreenEdge =
(bounds.left < (screenSize.x / 2)) ? bounds.left : (screenSize.x - bounds.left);
paddingForItem += distanceFromItemCenterToScreenEdge + POINT_SCAN_CUTOUT_RADIUS;
}
// Leave horizontal space for the item.
if (shouldPlaceMenuLeftOfBounds) {
fullMenu.setPadding(fullMenu.getPaddingLeft(), 0, paddingForItem, 0);
} else {
fullMenu.setPadding(paddingForItem, 0, fullMenu.getPaddingRight(), 0);
}
// Align the menuOverlay vertically with the item.
placeMenuOverlayAboveOrBelowBounds(bounds, true);
return shouldPlaceMenuLeftOfBounds;
}
@Override
public void draw(Canvas canvas, Paint paint) {
final float scale = mCurrentScale;
if (scale > 0) {
Rect bounds = getBounds();
float radius = (Math.min(bounds.width(), bounds.height()) / 2.0f);
float x = bounds.centerX();
float y = bounds.centerY();
// Background
if (scale != 1f && mBackgroundAlpha > 0) {
paint.setAlpha(mBackgroundAlpha);
canvas.drawCircle(x, y, radius, paint);
}
// Ripple
if (mRippleAlpha > 0) {
paint.setAlpha(mRippleAlpha);
canvas.drawCircle(x, y, radius * scale, paint);
}
}
}
private void makeErrorPath() {
final Rect bounds = this.bounds;
final int w2 = bounds.centerX();
final int h2 = bounds.centerY();
path1.reset();
path1.moveTo((float) (w2 - Math.cos(Math.toRadians(45)) * getRadius()), (float) (h2 - Math.sin(Math.toRadians(45)) * getRadius()));
path1.lineTo((float) (w2 + Math.cos(Math.toRadians(45)) * getRadius()), (float) (h2 + Math.sin(Math.toRadians(45)) * getRadius()));
pathMeasure1.setPath(path1, false);
mErrorPathLengthLeft = pathMeasure1.getLength();
path1.reset();
path1.moveTo((float) (w2 + Math.cos(Math.toRadians(45)) * getRadius()), (float) (h2 - Math.sin(Math.toRadians(45)) * getRadius()));
path1.lineTo((float) (w2 - Math.cos(Math.toRadians(45)) * getRadius()), (float) (h2 + Math.sin(Math.toRadians(45)) * getRadius()));
pathMeasure2.setPath(path1, false);
mErrorPathLengthRight = pathMeasure2.getLength();
}
@Override
public long getStartDelay(ViewGroup sceneRoot, SceneVisibilityTransition transition, TransitionPropagationResult result, boolean appear) {
int directionMultiplier = 1;
TransitionValues positionValues;
if (!appear) {
directionMultiplier = -1;
}
int viewCenterX = getViewX(result);
int viewCenterY = getViewY(result);
Rect epicenter = transition.getEpicenter();
int epicenterX;
int epicenterY;
if (epicenter != null) {
epicenterX = epicenter.centerX();
epicenterY = epicenter.centerY();
} else {
int[] loc = new int[2];
sceneRoot.getLocationOnScreen(loc);
epicenterX = Math.round(loc[0] + (sceneRoot.getWidth() / 2)
+ sceneRoot.getTranslationX());
epicenterY = Math.round(loc[1] + (sceneRoot.getHeight() / 2)
+ sceneRoot.getTranslationY());
}
float distance = distance(viewCenterX, viewCenterY, epicenterX, epicenterY);
float maxDistance = distance(0, 0, sceneRoot.getWidth(), sceneRoot.getHeight());
float distanceFraction = distance / maxDistance;
long duration = transition.getDuration();
if (duration < 0) {
duration = 300;
}
return Math.round(duration * directionMultiplier / mPropagationSpeed * distanceFraction);
}
@SuppressLint("DrawAllocation")
@Override
protected synchronized void onDraw(Canvas canvas) {
super.onDraw(canvas);
Rect rect = new Rect();
mPaint.getTextBounds(text, 0, this.text.length(), rect);
int x = (getWidth() / 2) - rect.centerX();
int y = (getHeight() / 2) - rect.centerY();
canvas.drawText(this.text, x, y, this.mPaint);
}
/**
* Set the icon offset
*
* @param viewBounds
*/
private void offsetIcon(Rect viewBounds) {
float startX = viewBounds.centerX() - (mPathBounds.width() / 2);
float offsetX = startX - mPathBounds.left;
float startY = viewBounds.centerY() - (mPathBounds.height() / 2);
float offsetY = startY - (mPathBounds.top);
mPath.offset(offsetX + mIconOffsetX, offsetY + mIconOffsetY);
}
public Rect clipSquare(Rect rect) {
int w = rect.width();
int h = rect.height();
int min = Math.min(w, h);
int cx = rect.centerX();
int cy = rect.centerY();
int r = min / 2;
return new Rect(
cx - r,
cy - r,
cx + r,
cy + r
);
}
public Rect getDrawRect() {
Rect original = getBounds();
int cX = original.centerX(), cY = original.centerY();
rect.left = cX - (fullSize ? bigImgSize : drawImgSize) / 2;
rect.right = cX + (fullSize ? bigImgSize : drawImgSize) / 2;
rect.top = cY - (fullSize ? bigImgSize : drawImgSize) / 2;
rect.bottom = cY + (fullSize ? bigImgSize : drawImgSize) / 2;
return rect;
}
private void drawBar(Canvas canvas, int level, int color) {
Rect bounds = getBounds();
int minLength = Math.min(bounds.width(), bounds.height());
float progressSize = minLength * 0.2f;
RectF rectF = new RectF(
bounds.centerX() - progressSize / 2,
bounds.centerY() - progressSize / 2,
bounds.centerX() + progressSize / 2,
bounds.centerY() + progressSize / 2);
mPaint.setColor(color);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(6);
if (level != 0)
canvas.drawArc(rectF, 0, (float) (level * 360 / maxLevel), false, mPaint);
}
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 void offsetIcon(Rect viewBounds) {
float startX = viewBounds.centerX() - (mPathBounds.width() / 2);
float offsetX = startX - mPathBounds.left;
float startY = viewBounds.centerY() - (mPathBounds.height() / 2);
float offsetY = startY - (mPathBounds.top);
mPath.offset(offsetX, offsetY);
}
/** Scales a rect about its centroid */
public 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);
}
}
/**
* Pre-Lollipop we use padding so that the shadow has enough space to be drawn. This method
* offsets our layout position so that we're positioned correctly if we're on one of
* our parent's edges.
*/
private void offsetIfNeeded(CoordinatorLayout parent, FloatingActionButton fab) {
final Rect padding = fab.mProgressPadding;
if (padding.centerX() > 0 && padding.centerY() > 0) {
final CoordinatorLayout.LayoutParams lp =
(CoordinatorLayout.LayoutParams) fab.getLayoutParams();
int offsetTB = 0, offsetLR = 0;
if (fab.getRight() >= parent.getWidth() - lp.rightMargin) {
// If we're on the left edge, shift it the right
offsetLR = padding.right;
} else if (fab.getLeft() <= lp.leftMargin) {
// If we're on the left edge, shift it the left
offsetLR = -padding.left;
}
if (fab.getBottom() >= parent.getBottom() - lp.bottomMargin) {
// If we're on the bottom edge, shift it down
offsetTB = padding.bottom;
} else if (fab.getTop() <= lp.topMargin) {
// If we're on the top edge, shift it up
offsetTB = -padding.top;
}
fab.offsetTopAndBottom(offsetTB);
fab.offsetLeftAndRight(offsetLR);
}
}
@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
int padding = bounds.centerX()/2;
shiftY = bounds.centerY()/8;
mBounds.left = bounds.left + padding;
mBounds.right = bounds.right - padding;
mBounds.top = bounds.top + padding;
mBounds.bottom = bounds.bottom - padding;
setupPauseMode();
}
private void measureDrawable(Rect bounds) {
mCenter = bounds.centerX();
int arrowMargin = bounds.width() / 50;
int arrowWidth = bounds.width() / 15;
int padding = mCenter - (int) (mCenter / Math.sqrt(2));
mArrowPoints[0] = new Point(mCenter - arrowMargin, mCenter - arrowMargin);
mArrowPoints[1] = new Point(mArrowPoints[0].x, mArrowPoints[0].y - arrowWidth);
mArrowPoints[2] = new Point(padding + arrowWidth, padding);
mArrowPoints[3] = new Point(padding, padding + arrowWidth);
mArrowPoints[4] = new Point(mArrowPoints[0].x - arrowWidth, mArrowPoints[0].y);
}
@Override
public long getStartDelay(ViewGroup sceneRoot, Transition transition,
TransitionValues startValues, TransitionValues endValues) {
if (startValues == null && endValues == null) {
return 0;
}
int directionMultiplier = 1;
Rect epicenter = transition.getEpicenter();
TransitionValues positionValues;
if (endValues == null || getViewVisibility(startValues) == View.VISIBLE) {
positionValues = startValues;
directionMultiplier = -1;
} else {
positionValues = endValues;
}
int viewCenterX = getViewX(positionValues);
int viewCenterY = getViewY(positionValues);
int[] loc = new int[2];
sceneRoot.getLocationOnScreen(loc);
int left = loc[0] + Math.round(sceneRoot.getTranslationX());
int top = loc[1] + Math.round(sceneRoot.getTranslationY());
int right = left + sceneRoot.getWidth();
int bottom = top + sceneRoot.getHeight();
int epicenterX;
int epicenterY;
if (epicenter != null) {
epicenterX = epicenter.centerX();
epicenterY = epicenter.centerY();
} else {
epicenterX = (left + right) / 2;
epicenterY = (top + bottom) / 2;
}
float distance = distance(sceneRoot, viewCenterX, viewCenterY, epicenterX, epicenterY,
left, top, right, bottom);
float maxDistance = getMaxDistance(sceneRoot);
float distanceFraction = distance/maxDistance;
long duration = transition.getDuration();
if (duration < 0) {
duration = 300;
}
return Math.round(duration * directionMultiplier / mPropagationSpeed * distanceFraction);
}
public int getHit(float x, float y) {
Rect r = computeLayout();
final float hysteresis = 20F;
int retval = GROW_NONE;
if (mCircle) {
float distX = x - r.centerX();
float distY = y - r.centerY();
int distanceFromCenter = (int) Math.sqrt(distX * distX + distY
* distY);
int radius = mDrawRect.width() / 2;
int delta = distanceFromCenter - radius;
if (Math.abs(delta) <= hysteresis) {
if (Math.abs(distY) > Math.abs(distX)) {
if (distY < 0) {
retval = GROW_TOP_EDGE;
} else {
retval = GROW_BOTTOM_EDGE;
}
} else {
if (distX < 0) {
retval = GROW_LEFT_EDGE;
} else {
retval = GROW_RIGHT_EDGE;
}
}
} else if (distanceFromCenter < radius) {
retval = MOVE;
} else {
retval = GROW_NONE;
}
} else {
// verticalCheck makes sure the position is between the top and
// the bottom edge (with some tolerance). Similar for horizCheck.
boolean verticalCheck = (y >= r.top - hysteresis)
&& (y < r.bottom + hysteresis);
boolean horizCheck = (x >= r.left - hysteresis)
&& (x < r.right + hysteresis);
// Check whether the position is near some edge(s).
if ((Math.abs(r.left - x) < hysteresis) && verticalCheck) {
retval |= GROW_LEFT_EDGE;
}
if ((Math.abs(r.right - x) < hysteresis) && verticalCheck) {
retval |= GROW_RIGHT_EDGE;
}
if ((Math.abs(r.top - y) < hysteresis) && horizCheck) {
retval |= GROW_TOP_EDGE;
}
if ((Math.abs(r.bottom - y) < hysteresis) && horizCheck) {
retval |= GROW_BOTTOM_EDGE;
}
// Not near any edge but inside the rectangle: move.
if (retval == GROW_NONE && r.contains((int) x, (int) y)) {
retval = MOVE;
}
}
return retval;
}
/** Returns a point in the center of the visible bounds of this object. */
public Point getVisibleCenter() {
Rect bounds = getVisibleBounds();
return new Point(bounds.centerX(), bounds.centerY());
}
private void calcRadius() {
Rect bounds = getBounds();
float x1 = bounds.centerX();
float y1 = bounds.centerY();
finalRadius = (float) Math.ceil(Math.sqrt((bounds.left - x1) * (bounds.left - x1) + (bounds.top - y1) * (bounds.top - y1)));
}
@OnClick(R.id.reset) void resetUi(View resetCard) {
cardsLine.setVisibility(View.INVISIBLE);
final View target = ButterKnife.findById(this, R.id.activator);
// Coordinates of circle initial point
final ViewGroup parent = (ViewGroup) activatorMask.getParent();
final Rect bounds = new Rect();
final Rect maskBounds = new Rect();
target.getDrawingRect(bounds);
activatorMask.getDrawingRect(maskBounds);
parent.offsetDescendantRectToMyCoords(target, bounds);
parent.offsetDescendantRectToMyCoords(activatorMask, maskBounds);
maskElevation = activatorMask.getCardElevation();
activatorMask.setCardElevation(0);
final int cX = maskBounds.centerX();
final int cY = maskBounds.centerY();
final Animator circularReveal = ViewAnimationUtils.createCircularReveal(activatorMask, cX, cY,
(float) Math.hypot(maskBounds.width() * .5f, maskBounds.height() * .5f),
target.getWidth() / 2f, View.LAYER_TYPE_HARDWARE);
final float c0X = bounds.centerX() - maskBounds.centerX();
final float c0Y = bounds.centerY() - maskBounds.centerY();
AnimatorPath path = new AnimatorPath();
path.moveTo(0, 0);
path.curveTo(0, 0, 0, c0Y, c0X, c0Y);
ObjectAnimator pathAnimator = ObjectAnimator.ofObject(this, "maskLocation", new PathEvaluator(),
path.getPoints().toArray());
AnimatorSet set = new AnimatorSet();
set.playTogether(circularReveal, pathAnimator);
set.setInterpolator(new FastOutSlowInInterpolator());
set.setDuration(SLOW_DURATION);
set.addListener(new AnimatorListenerAdapter() {
@Override public void onAnimationEnd(Animator animation) {
activatorMask.setCardElevation(maskElevation);
activatorMask.setVisibility(View.INVISIBLE);
circlesLine.setVisibility(View.VISIBLE);
executeCirclesDropDown();
target.setEnabled(true);
}
});
set.start();
}