下面列出了android.graphics.Rect#exactCenterY ( ) 实例代码,或者点击链接到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();
}
@Override
public void draw(Canvas canvas) {
Rect bounds = getBounds();
float totalWidth = bounds.width();
float minWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, MIN_WIDTH_DP, mDisplayMetrics);
if (totalWidth < minWidth)
totalWidth = minWidth;
float centerY = bounds.exactCenterY();
float startX = bounds.left;
float stopX;
float gapWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, GAP_WIDTH_DP, mDisplayMetrics);
// Draw the lines before the gaps
for (float startPercentage : mGapPercentages) {
stopX = totalWidth * startPercentage;
canvas.drawLine(startX, centerY, stopX, centerY, mPaint);
startX = stopX + gapWidth;
}
canvas.drawLine(startX, centerY, totalWidth, centerY, mPaint);
}
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);
}
}
/**
* Calculates the chip icon's ChipDrawable-absolute bounds (top-left is <code>
* [ChipDrawable.getBounds().left, ChipDrawable.getBounds().top]</code>).
*/
private void calculateChipIconBounds(@NonNull Rect bounds, @NonNull RectF outBounds) {
outBounds.setEmpty();
if (showsChipIcon() || showsCheckedIcon()) {
float offsetFromStart = chipStartPadding + iconStartPadding;
float chipWidth = getCurrentChipIconWidth();
if (DrawableCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_LTR) {
outBounds.left = bounds.left + offsetFromStart;
outBounds.right = outBounds.left + chipWidth;
} else {
outBounds.right = bounds.right - offsetFromStart;
outBounds.left = outBounds.right - chipWidth;
}
float chipHeight = getCurrentChipIconHeight();
outBounds.top = bounds.exactCenterY() - chipHeight / 2f;
outBounds.bottom = outBounds.top + chipHeight;
}
}
private float computeTimeYOffset(Rect textBounds, Rect watchBounds) {
if (mSettings.isShowWearIcon() || (!mSettings.isShowInfoBarAmbient() && mAmbient)) {
return watchBounds.exactCenterY() + (textBounds.height()
/ 4.0f);
}
// this positions the time in the exact center but generally looks... off. So we will position
// it slightly up to look more right
// else if (!mSettings.isShowInfoBarAmbient() && mAmbient) {
// return watchBounds.exactCenterY() + (textBounds.height() / 2.0f);
// }
else {
return watchBounds.exactCenterY();
}
}
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);
}
}
@Override
public void draw(Canvas canvas) {
if(mBitmap != null){
Rect bounds = getBounds();
float x = bounds.exactCenterX();
float y = bounds.exactCenterY();
float radius = bounds.height() / 2f;
mPaint.setShader(mBitmapShader);
canvas.drawCircle(x, y, radius, 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(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 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 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 update() {
final Rect bounds = getBounds();
if (bounds.isEmpty()) {
mRadius = 0;
return;
}
final float x = bounds.exactCenterX();
final float y = bounds.exactCenterY();
mRadius = (float) Math.sqrt(x * x + y * y);
if (mRippleRadius <= 0)
mRippleRadius = mMaxCount <= 0 ? mRadius : mRadius / mMaxCount;
}
@Override
protected void onBoundsChange(Rect bounds) {
float x = bounds.exactCenterX();
float y = bounds.exactCenterY();
mPath.reset();
mPath.moveTo(x, y + mSize / 2f);
mPath.lineTo(x - mSize, y - mSize / 2f);
mPath.lineTo(x + mSize, y - mSize / 2f);
mPath.close();
}
@Override
public void draw(Canvas canvas) {
Rect bounds = getBounds();
float totalWidth = bounds.width();
float minWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, MIN_WIDTH_DP, mDisplayMetrics);
if (totalWidth < minWidth)
totalWidth = minWidth;
float gapWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, GAP_WIDTH_DP, mDisplayMetrics);
float centerY = bounds.exactCenterY();
float startX = bounds.left;
float stopX;
totalWidth += gapWidth;
for (float startPercentage : mGapPercentages) {
stopX = bounds.left + (totalWidth * startPercentage) - gapWidth;
if (stopX < bounds.left) {
startX = bounds.left + (totalWidth * startPercentage);
continue;
}
canvas.drawLine(startX, centerY, stopX, centerY, mPaint);
startX = stopX + gapWidth;
}
canvas.drawLine(startX, centerY, totalWidth, centerY, 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(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 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);
}
}
@Override
protected void onBoundsChange(@NonNull Rect bounds) {
final int width = bounds.width();
final int height = bounds.height();
paint.setTextSize(height);
paint.getTextBounds(text, 0, 1, drawBounds);
paint.setTextSize(Math.min(height, (int) Math.ceil(
width * (height / (float) drawBounds.width()))));
paint.getTextBounds(text, 0, 1, drawBounds);
drawBounds.offsetTo(bounds.left + (width - drawBounds.width()) / 2,
bounds.top + (height - drawBounds.height()) / 2 - drawBounds.bottom);
centerX = bounds.exactCenterX();
centerY = bounds.exactCenterY();
}
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
protected void onBoundsChange(Rect bounds) {
mX = bounds.exactCenterX();
mY = bounds.exactCenterY();
mRadius = Math.min(bounds.width(), bounds.height()) / 2f;
}