下面列出了android.graphics.Rect#exactCenterX ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Function to draw image in the center of arc
*
* @param canvas Canvas to draw
* @param tempAngle Temporary angle
* @param bitmap Bitmap to draw
*/
private void drawImage(Canvas canvas, float tempAngle, Bitmap bitmap) {
//get every arc img width and angle
int imgWidth = (radius / mWheelItems.size()) - mImagePadding;
float angle = (float) ((tempAngle + 360 / mWheelItems.size() / 2) * Math.PI / 180);
//calculate x and y
int x = (int) (center + radius / 2 / 2 * Math.cos(angle));
int y = (int) (center + radius / 2 / 2 * Math.sin(angle));
//create arc to draw
Rect rect = new Rect(x - imgWidth / 2, y - imgWidth / 2, x + imgWidth / 2, y + imgWidth / 2);
//rotate main bitmap
float px = rect.exactCenterX();
float py = rect.exactCenterY();
Matrix matrix = new Matrix();
matrix.postTranslate(-bitmap.getWidth() / 2, -bitmap.getHeight() / 2);
matrix.postRotate(tempAngle + 120);
matrix.postTranslate(px, py);
canvas.drawBitmap(bitmap, matrix, new Paint( Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.FILTER_BITMAP_FLAG ));
Log.d("sadsdsddssd" , bitmap.getWidth() + " : "+bitmap.getHeight());
matrix.reset();
}
protected void positionSelectorLikeFocusCompat(int position, View sel) {
// If we're changing position, update the visibility since the selector
// is technically being detached from the previous selection.
final Drawable selector = getSelector();
final boolean manageState = selector != null && position != INVALID_POSITION;
if (manageState) {
selector.setVisible(false, false);
}
positionSelectorCompat(position, sel);
if (manageState) {
final Rect bounds = mSelectorRect;
final float x = bounds.exactCenterX();
final float y = bounds.exactCenterY();
selector.setVisible(getVisibility() == VISIBLE, false);
DrawableCompat.setHotspot(selector, x, y);
}
}
private void drawTriangle(Canvas c, float startAngle, float sweepAngle, Rect bounds) {
if (this.mShowArrow) {
if (this.mArrow == null) {
this.mArrow = new Path();
this.mArrow.setFillType(FillType.EVEN_ODD);
} else {
this.mArrow.reset();
}
float inset = ((float) (((int) this.mStrokeInset) / 2)) * this.mArrowScale;
float x = (float) ((this.mRingCenterRadius * Math.cos(0.0d)) + ((double) bounds.exactCenterX()));
float y = (float) ((this.mRingCenterRadius * Math.sin(0.0d)) + ((double) bounds.exactCenterY()));
this.mArrow.moveTo(0.0f, 0.0f);
this.mArrow.lineTo(((float) this.mArrowWidth) * this.mArrowScale, 0.0f);
this.mArrow.lineTo((((float) this.mArrowWidth) * this.mArrowScale) / 2.0f, ((float) this.mArrowHeight) * this.mArrowScale);
this.mArrow.offset(x - inset, y);
this.mArrow.close();
this.mArrowPaint.setColor(this.mCurrentColor);
c.rotate((startAngle + sweepAngle) - 5.0f, bounds.exactCenterX(), bounds.exactCenterY());
c.drawPath(this.mArrow, this.mArrowPaint);
}
}
@UiThread public static void revealPopupWindow(@NonNull PopupWindow popupWindow, @NonNull View from) {
Rect rect = ViewHelper.getLayoutPosition(from);
int x = (int) rect.exactCenterX();
int y = (int) rect.exactCenterY();
if (popupWindow.getContentView() != null) {
View view = popupWindow.getContentView();
if (view != null) {
popupWindow.showAsDropDown(from);
view.post(() -> {
if (ViewCompat.isAttachedToWindow(view)) {
Animator animator = ViewAnimationUtils.createCircularReveal(view, x, y, 0,
(float) Math.hypot(rect.width(), rect.height()));
animator.setDuration(view.getResources().getInteger(android.R.integer.config_shortAnimTime));
animator.start();
}
});
}
}
}
@Override
@SuppressLint("NewApi")
public void draw(@NonNull Canvas canvas) {
if (text.length() == 0) {
return;
}
if (paintPreparationNeeded) {
paintPreparationNeeded = false;
onPrepareBadgePaint(badgePaint);
onPrepareTextPaint(textPaint);
}
Rect rect = shape.draw(canvas, getBounds(), badgePaint, getLayoutDirection());
textPaint.setTextSize(rect.height() * MAGIC_TEXT_SCALE_FACTOR);
float x = rect.exactCenterX();
float y = rect.exactCenterY() - (textPaint.ascent() + textPaint.descent()) * 0.5f;
canvas.drawText(text, x, y, textPaint);
}
@Override
public void draw(Canvas canvas) {
final Rect r = getBounds();
float cx = r.exactCenterX();
float cy = r.exactCenterY();
canvas.drawCircle(cx, cy, Math.min(cx, cy), mPaint);
}
private void drawTriangle(Canvas c, float startAngle, float sweepAngle, Rect bounds) {
if (mShowArrow) {
if (mArrow == null) {
mArrow = new android.graphics.Path();
mArrow.setFillType(android.graphics.Path.FillType.EVEN_ODD);
} else {
mArrow.reset();
}
// Adjust the position of the triangle so that it is inset as
// much as the arc, but also centered on the arc.
float inset = (int) mStrokeInset / 2 * mArrowScale;
float x = (float) (mRingCenterRadius * Math.cos(0) + bounds.exactCenterX());
float y = (float) (mRingCenterRadius * Math.sin(0) + bounds.exactCenterY());
// Update the path each time. This works around an issue in SKIA
// where concatenating a rotation matrix to a scale matrix
// ignored a starting negative rotation. This appears to have
// been fixed as of API 21.
mArrow.moveTo(0, 0);
mArrow.lineTo(mArrowWidth * mArrowScale, 0);
mArrow.lineTo((mArrowWidth * mArrowScale / 2), (mArrowHeight
* mArrowScale));
mArrow.offset(x - inset, y);
mArrow.close();
// draw a triangle
mArrowPaint.setColor(mColors[mColorIndex]);
c.rotate(startAngle + sweepAngle - ARROW_OFFSET_ANGLE, bounds.exactCenterX(),
bounds.exactCenterY());
c.drawPath(mArrow, mArrowPaint);
}
}
protected void drawCompass(final Canvas canvas, final float bearing, final Rect screenRect) {
final Projection proj = mMapView.getProjection();
float centerX;
float centerY;
if (mInCenter) {
final Rect rect = proj.getScreenRect();
centerX = rect.exactCenterX();
centerY = rect.exactCenterY();
} else {
centerX = mCompassCenterX * mScale;
centerY = mCompassCenterY * mScale;
}
mCompassMatrix.setTranslate(-mCompassFrameCenterX, -mCompassFrameCenterY);
mCompassMatrix.postTranslate(centerX, centerY);
proj.save(canvas, false, true);
canvas.concat(mCompassMatrix);
canvas.drawBitmap(mCompassFrameBitmap, 0, 0, sSmoothPaint);
proj.restore(canvas, true);
mCompassMatrix.setRotate(-bearing, mCompassRoseCenterX, mCompassRoseCenterY);
mCompassMatrix.postTranslate(-mCompassRoseCenterX, -mCompassRoseCenterY);
mCompassMatrix.postTranslate(centerX, centerY);
proj.save(canvas, false, true);
canvas.concat(mCompassMatrix);
canvas.drawBitmap(mCompassRoseBitmap, 0, 0, sSmoothPaint);
proj.restore(canvas, true);
}
private void drawTriangle(Canvas c, float startAngle, float sweepAngle, Rect bounds) {
if (mShowArrow) {
if (mArrow == null) {
mArrow = new android.graphics.Path();
mArrow.setFillType(android.graphics.Path.FillType.EVEN_ODD);
} else {
mArrow.reset();
}
// Adjust the position of the triangle so that it is inset as
// much as the arc, but also centered on the arc.
float inset = (int) mStrokeInset / 2 * mArrowScale;
float x = (float) (mRingCenterRadius * Math.cos(0) + bounds.exactCenterX());
float y = (float) (mRingCenterRadius * Math.sin(0) + bounds.exactCenterY());
// Update the path each time. This works around an issue in SKIA
// where concatenating a rotation matrix to a scale matrix
// ignored a starting negative rotation. This appears to have
// been fixed as of API 21.
mArrow.moveTo(0, 0);
mArrow.lineTo(mArrowWidth * mArrowScale, 0);
mArrow.lineTo((mArrowWidth * mArrowScale / 2), (mArrowHeight
* mArrowScale));
mArrow.offset(x - inset, y);
mArrow.close();
// draw a triangle
mArrowPaint.setColor(mColors[mColorIndex]);
c.rotate(startAngle + sweepAngle - ARROW_OFFSET_ANGLE, bounds.exactCenterX(),
bounds.exactCenterY());
c.drawPath(mArrow, mArrowPaint);
}
}
private void init() {
if (mPaint == null) {
initPaint();
}
mPath = new Path();
Rect bounds = new Rect();
bounds.set(getBounds());
bounds.inset(10, 10); // apply some padding
final int x = 3;
final float angle = 360 / x;
final double rads = Math.toRadians(angle);
float exactCenterX = bounds.exactCenterX();
float exactCenterY = bounds.exactCenterY();
float widthOffset = (float) ((bounds.width() / 2) * Math.sin(rads));
float heightOffset = (float) ((bounds.height() / 2) * Math.cos(rads));
// move to the first point
mPath.moveTo(exactCenterX - widthOffset, exactCenterY - heightOffset);
for (int i = 2; i <= x; i++) {
// draw the other 2 points
mPath.lineTo((float) (exactCenterX - ((bounds.width() / 2) * Math.sin(rads * i))),
(float) (exactCenterY - ((bounds.height() / 2) * Math.cos(rads * i))));
}
mPath.moveTo(exactCenterX + widthOffset, exactCenterY + heightOffset);
for (int i = 2; i <= x; i++) {
mPath.lineTo((float) (exactCenterX + ((bounds.width() / 2) * Math.sin(rads * i))),
(float) (exactCenterY + ((bounds.height() / 2) * Math.cos(rads * i))));
}
}
@Override
public void draw(Canvas canvas) {
Rect r = getBounds();
float centerX = r.exactCenterX();
float centerY = r.exactCenterY();
canvas.drawCircle(centerX, centerY, mOuterRadius, mOuterPaint);
canvas.drawCircle(centerX, centerY, mCenterRadius, mCenterPaint);
if (mBorderPaint != null)
canvas.drawCircle(centerX, centerY, mBorderRadius, mBorderPaint);
}
private void drawTriangle(Canvas c, float startAngle, float sweepAngle, Rect bounds) {
if (mShowArrow) {
if (mArrow == null) {
mArrow = new android.graphics.Path();
mArrow.setFillType(android.graphics.Path.FillType.EVEN_ODD);
} else {
mArrow.reset();
}
// Adjust the position of the triangle so that it is inset as
// much as the arc, but also centered on the arc.
float x = (float) (mRingCenterRadius * Math.cos(0) + bounds.exactCenterX());
float y = (float) (mRingCenterRadius * Math.sin(0) + bounds.exactCenterY());
// Update the path each time. This works around an issue in SKIA
// where concatenating a rotation matrix to a scale matrix
// ignored a starting negative rotation. This appears to have
// been fixed as of API 21.
mArrow.moveTo(0, 0);
mArrow.lineTo((mArrowWidth) * mArrowScale, 0);
mArrow.lineTo(((mArrowWidth) * mArrowScale / 2), (mArrowHeight
* mArrowScale));
mArrow.offset(x-((mArrowWidth) * mArrowScale / 2), y);
mArrow.close();
// draw a triangle
mArrowPaint.setColor(mColors[mColorIndex]);
//when sweepAngle < 0 adjust the position of the arrow
c.rotate(startAngle + (sweepAngle<0?0:sweepAngle) - ARROW_OFFSET_ANGLE, bounds.exactCenterX(),
bounds.exactCenterY());
c.drawPath(mArrow, mArrowPaint);
}
}
private void drawTriangle(Canvas c, float startAngle, float sweepAngle, Rect bounds) {
if (mShowArrow) {
if (mArrow == null) {
mArrow = new android.graphics.Path();
mArrow.setFillType(android.graphics.Path.FillType.EVEN_ODD);
} else {
mArrow.reset();
}
// Adjust the position of the triangle so that it is inset as
// much as the arc, but also centered on the arc.
float inset = (int) mStrokeInset / 2 * mArrowScale;
float x = (float) (mRingCenterRadius * Math.cos(0) + bounds.exactCenterX());
float y = (float) (mRingCenterRadius * Math.sin(0) + bounds.exactCenterY());
// Update the path each time. This works around an issue in SKIA
// where concatenating a rotation matrix to a scale matrix
// ignored a starting negative rotation. This appears to have
// been fixed as of API 21.
mArrow.moveTo(0, 0);
mArrow.lineTo(mArrowWidth * mArrowScale, 0);
mArrow.lineTo((mArrowWidth * mArrowScale / 2), (mArrowHeight
* mArrowScale));
mArrow.offset(x - inset, y);
mArrow.close();
// draw a triangle
mArrowPaint.setColor(mColors[mColorIndex]);
c.rotate(startAngle + sweepAngle - ARROW_OFFSET_ANGLE, bounds.exactCenterX(),
bounds.exactCenterY());
c.drawPath(mArrow, mArrowPaint);
}
}
private void drawTriangle(Canvas c, float startAngle, float sweepAngle, Rect bounds) {
if (mShowArrow) {
if (mArrow == null) {
mArrow = new android.graphics.Path();
mArrow.setFillType(android.graphics.Path.FillType.EVEN_ODD);
} else {
mArrow.reset();
}
// Adjust the position of the triangle so that it is inset as
// much as the arc, but also centered on the arc.
float x = (float) (mRingCenterRadius * Math.cos(0) + bounds.exactCenterX());
float y = (float) (mRingCenterRadius * Math.sin(0) + bounds.exactCenterY());
// Update the path each time. This works around an issue in SKIA
// where concatenating a rotation matrix to a scale matrix
// ignored a starting negative rotation. This appears to have
// been fixed as of API 21.
mArrow.moveTo(0, 0);
mArrow.lineTo((mArrowWidth) * mArrowScale, 0);
mArrow.lineTo(((mArrowWidth) * mArrowScale / 2), (mArrowHeight
* mArrowScale));
mArrow.offset(x-((mArrowWidth) * mArrowScale / 2), y);
mArrow.close();
// draw a triangle
mArrowPaint.setColor(mColors[mColorIndex]);
//when sweepAngle < 0 adjust the position of the arrow
c.rotate(startAngle + (sweepAngle<0?0:sweepAngle) - ARROW_OFFSET_ANGLE, bounds.exactCenterX(),
bounds.exactCenterY());
c.drawPath(mArrow, mArrowPaint);
}
}
private void drawTriangle(Canvas c, float startAngle, float sweepAngle, Rect bounds) {
if (mShowArrow) {
if (mArrow == null) {
mArrow = new android.graphics.Path();
mArrow.setFillType(android.graphics.Path.FillType.EVEN_ODD);
} else {
mArrow.reset();
}
// Adjust the position of the triangle so that it is inset as
// much as the arc, but also centered on the arc.
float inset = (int) mStrokeInset / 2 * mArrowScale;
float x = (float) (mRingCenterRadius * Math.cos(0) + bounds.exactCenterX());
float y = (float) (mRingCenterRadius * Math.sin(0) + bounds.exactCenterY());
// Update the path each time. This works around an issue in SKIA
// where concatenating a rotation matrix to a scale matrix
// ignored a starting negative rotation. This appears to have
// been fixed as of API 21.
mArrow.moveTo(0, 0);
mArrow.lineTo(mArrowWidth * mArrowScale, 0);
mArrow.lineTo((mArrowWidth * mArrowScale / 2), (mArrowHeight
* mArrowScale));
mArrow.offset(x - inset, y);
mArrow.close();
// draw a triangle
mArrowPaint.setColor(mColors[mColorIndex]);
mArrowPaint.setAlpha(mAlpha);
c.rotate(startAngle + sweepAngle - ARROW_OFFSET_ANGLE, bounds.exactCenterX(),
bounds.exactCenterY());
c.drawPath(mArrow, mArrowPaint);
}
}
private void drawTriangle(Canvas c, float startAngle, float sweepAngle, Rect bounds) {
if (mShowArrow) {
if (mArrow == null) {
mArrow = new android.graphics.Path();
mArrow.setFillType(android.graphics.Path.FillType.EVEN_ODD);
} else {
mArrow.reset();
}
// Adjust the position of the triangle so that it is inset as
// much as the arc, but also centered on the arc.
float inset = (int) mStrokeInset / 2 * mArrowScale;
float x = (float) (mRingCenterRadius * Math.cos(0) + bounds.exactCenterX());
float y = (float) (mRingCenterRadius * Math.sin(0) + bounds.exactCenterY());
// Update the path each time. This works around an issue in SKIA
// where concatenating a rotation matrix to a scale matrix
// ignored a starting negative rotation. This appears to have
// been fixed as of API 21.
mArrow.moveTo(0, 0);
mArrow.lineTo(mArrowWidth * mArrowScale, 0);
mArrow.lineTo((mArrowWidth * mArrowScale / 2), (mArrowHeight
* mArrowScale));
mArrow.offset(x - inset, y);
mArrow.close();
// draw a triangle
mArrowPaint.setColor(mCurrentColor);
c.rotate(startAngle + sweepAngle - ARROW_OFFSET_ANGLE, bounds.exactCenterX(),
bounds.exactCenterY());
c.drawPath(mArrow, mArrowPaint);
}
}
private void drawTriangle(Canvas c, float startAngle, float sweepAngle, Rect bounds) {
if (mShowArrow) {
if (mArrow == null) {
mArrow = new android.graphics.Path();
mArrow.setFillType(android.graphics.Path.FillType.EVEN_ODD);
} else {
mArrow.reset();
}
// Adjust the position of the triangle so that it is inset as
// much as the arc, but also centered on the arc.
float x = (float) (mRingCenterRadius * Math.cos(0) + bounds.exactCenterX());
float y = (float) (mRingCenterRadius * Math.sin(0) + bounds.exactCenterY());
// Update the path each time. This works around an issue in SKIA
// where concatenating a rotation matrix to a scale matrix
// ignored a starting negative rotation. This appears to have
// been fixed as of API 21.
mArrow.moveTo(0, 0);
mArrow.lineTo((mArrowWidth) * mArrowScale, 0);
mArrow.lineTo(((mArrowWidth) * mArrowScale / 2), (mArrowHeight
* mArrowScale));
mArrow.offset(x-((mArrowWidth) * mArrowScale / 2), y);
mArrow.close();
// draw a triangle
mArrowPaint.setColor(mColors[mColorIndex]);
//when sweepAngle < 0 adjust the position of the arrow
c.rotate(startAngle + (sweepAngle<0?0:sweepAngle) - ARROW_OFFSET_ANGLE, bounds.exactCenterX(),
bounds.exactCenterY());
c.drawPath(mArrow, mArrowPaint);
}
}
private float computeXOffset(String text, Paint paint, Rect watchBounds) {
float centerX = watchBounds.exactCenterX();
float textLength = paint.measureText(text);
return centerX - (textLength / 2.0f);
}
private int[] getCenterClickedView(ViewGroup from) {
Rect clickedViewRect = new Rect();
clickedView.getDrawingRect(clickedViewRect);
from.offsetDescendantRectToMyCoords(clickedView, clickedViewRect);
return new int[] {(int) clickedViewRect.exactCenterX(), (int) clickedViewRect.exactCenterY()};
}
@Override
public void draw(Canvas canvas) {
if (!isVisible())
return;
if (mRippleRadius <= 0)
return;
if (mRadius <= 0)
return;
final int[] state = getState();
final int rippleShowColor = DrawableHelper.getColor(mStartColor, state, mAlpha);
final int rippleHideColor = DrawableHelper.getColor(mEndColor, state, mAlpha);
final Rect bounds = getBounds();
final float x = bounds.exactCenterX();
final float y = bounds.exactCenterY();
final float animate = getAnimatedValue();
final int[] colors;
final float[] stops;
final float radius = mRadius;
final float p = mRippleRadius / radius;
final float edge = 0.001f;
final ArrayList<Float> ass = tStops;
final ArrayList<Integer> acs = tColors;
ass.clear();
acs.clear();
final float base = p * animate;
float value = base;
ass.add(value);
acs.add(rippleHideColor);
value = base - p;
while (value > 0) {
ass.add(0, value + p - edge);
acs.add(0, rippleShowColor);
ass.add(0, value);
acs.add(0, rippleHideColor);
value -= p;
}
if (value + p - edge <= 0) {
ass.add(0, 0f);
acs.add(0, rippleHideColor);
} else {
ass.add(0, value + p - edge);
acs.add(0, rippleShowColor);
ass.add(0, 0f);
acs.add(0, DrawableHelper.evaluateColor(-value / p, rippleHideColor,
rippleShowColor));
}
value = base + p;
while (value < 1) {
ass.add(value - edge);
acs.add(rippleShowColor);
ass.add(value);
acs.add(rippleHideColor);
value += p;
}
if (value == 1) {
ass.add(1f);
acs.add(rippleShowColor);
} else {
ass.add(1f);
acs.add(DrawableHelper.evaluateColor((p - (value - 1)) / p, rippleHideColor,
rippleShowColor));
}
final int size = ass.size();
if (size <= 1)
return;
stops = new float[size];
colors = new int[size];
for (int i = 0; i < size; i++) {
stops[i] = ass.get(i);
colors[i] = acs.get(i);
}
mPaint.setShader(new RadialGradient(x, y, radius, colors, stops, Shader.TileMode.CLAMP));
if (mClipStart) {
if (mStartClipSize < radius) {
mStartClipSize = (getRepeatCompletedCount() + animate) * mRippleRadius;
if (mStartClipSize < radius)
canvas.drawCircle(x, y, mStartClipSize, mPaint);
else
canvas.drawCircle(x, y, radius, mPaint);
} else {
canvas.drawCircle(x, y, radius, mPaint);
}
} else {
canvas.drawCircle(x, y, radius, mPaint);
}
}