下面列出了android.graphics.Path#close ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
public void rightPath(RectF rect, Path path) {
path.moveTo(mAngle, rect.top);
path.lineTo(rect.width(), rect.top);
path.arcTo(
new RectF(rect.right - mAngle * 2 - mArrowWidth, rect.top, rect.right - mArrowWidth,
mAngle * 2 + rect.top), 270, 90);
path.lineTo(rect.right - mArrowWidth, mArrowTop);
path.lineTo(rect.right, mArrowTop - mArrowOffset);
path.lineTo(rect.right - mArrowWidth, mArrowTop + mArrowHeight);
path.lineTo(rect.right - mArrowWidth, rect.height() - mAngle);
path.arcTo(new RectF(rect.right - mAngle * 2 - mArrowWidth, rect.bottom - mAngle * 2,
rect.right - mArrowWidth, rect.bottom), 0, 90);
path.lineTo(rect.left, rect.bottom);
path.arcTo(
new RectF(rect.left, rect.bottom - mAngle * 2, mAngle * 2 + rect.left, rect.bottom), 90,
90);
path.lineTo(rect.left, rect.top);
path.arcTo(new RectF(rect.left, rect.top, mAngle * 2 + rect.left, mAngle * 2 + rect.top),
180, 90);
path.close();
}
@Override
public void handle(Canvas canvas) {
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(8);
//中间画布操作
canvas.drawLine(startPoint.x, startPoint.y, endPoint.x, endPoint.y, paint);
Path triangle = new Path();
Point triangleP[] = getTrianPoint(startPoint.x, startPoint.y, endPoint.x, endPoint.y);
triangle.moveTo(triangleP[0].x, triangleP[0].y);
triangle.lineTo(triangleP[1].x, triangleP[1].y);
triangle.lineTo(triangleP[2].x, triangleP[2].y);
triangle.close();
paint.setStyle(Paint.Style.FILL);
canvas.drawPath(triangle, paint);
paint.setStyle(Paint.Style.STROKE);
}
public void rightPath(RectF rect, Path path) {
path.moveTo(mAngle, rect.top);
path.lineTo(rect.width(), rect.top);
path.arcTo(new RectF(rect.right - mAngle * 2 - mArrowWidth, rect.top,
rect.right - mArrowWidth, mAngle * 2 + rect.top), 270, 90);
path.lineTo(rect.right - mArrowWidth, mArrowTop);
path.lineTo(rect.right, mArrowTop - mArrowOffset);
path.lineTo(rect.right - mArrowWidth, mArrowTop + mArrowHeight);
path.lineTo(rect.right - mArrowWidth, rect.height() - mAngle);
path.arcTo(new RectF(rect.right - mAngle * 2 - mArrowWidth, rect.bottom
- mAngle * 2, rect.right - mArrowWidth, rect.bottom), 0, 90);
path.lineTo(rect.left, rect.bottom);
path.arcTo(new RectF(rect.left, rect.bottom - mAngle * 2, mAngle * 2
+ rect.left, rect.bottom), 90, 90);
path.lineTo(rect.left, rect.top);
path.arcTo(new RectF(rect.left, rect.top, mAngle * 2 + rect.left,
mAngle * 2 + rect.top), 180, 90);
path.close();
}
public RectF getPathRect() {
List<Point> list = new ArrayList<>();
for (int i = 0; i < count; i++) {
int x, y;
x = (int) (centerX + percents[i] * radius * Math.cos(angle * i + Math.PI / 2));
y = (int) (centerY - percents[i] * radius * Math.sin(angle * i + Math.PI / 2));
Point p = new Point();
p.set(x, y);
list.add(p);
}
Path path = new Path();
for (int i = 0; i < list.size(); i++) {
if (i == 0) {
path.moveTo(list.get(i).x, list.get(i).y);
} else {
path.lineTo(list.get(i).x, list.get(i).y);
}
}
path.close();
RectF rect = new RectF();
path.computeBounds(rect, true);
return rect;
}
private void drawCircleProgress(Canvas canvas) {
int centerX = getWidth() / 2;
int centerY = getHeight() / 2;
canvas.drawCircle(centerX, centerY, mRadius, mBgPaint);
if (strokeWidth > 0) {
canvas.drawCircle(getWidth() / 2, getHeight() / 2, mRadius, mStrokePaint);
}
Path path = new Path();
path.moveTo(centerX, centerY);
path.lineTo(centerX, 0);
RectF rectF = new RectF(0, 0, getRight(), getBottom());
path.arcTo(rectF, 270, mProgress / mMaxProgress * 360);
path.close();
canvas.drawPath(path, mProgressPaint);
}
private void initBottomSquarePath(RectF rect, Path path, float strokeWidth) {
path.moveTo(rect.left + strokeWidth, rect.top + strokeWidth);
path.lineTo(rect.right - strokeWidth, rect.top + strokeWidth);
path.lineTo(rect.right - strokeWidth, rect.bottom - getArrowHeight() - strokeWidth);
path.lineTo(rect.left + getArrowWidth() + getArrowPosition() - (strokeWidth / 2), rect.bottom - getArrowHeight() - strokeWidth);
path.lineTo(rect.left + getArrowPosition() + getArrowWidth() / 2, rect.bottom - strokeWidth - strokeWidth);
path.lineTo(rect.left + getArrowPosition() + (strokeWidth / 2), rect.bottom - getArrowHeight() - strokeWidth);
path.lineTo(rect.left + getArrowPosition() + strokeWidth, rect.bottom - getArrowHeight() - strokeWidth);
path.lineTo(rect.left + strokeWidth, rect.bottom - getArrowHeight() - strokeWidth);
path.lineTo(rect.left + strokeWidth, rect.top + strokeWidth);
path.close();
}
private Path makePathAndBoundingBox(SVG.Ellipse obj)
{
float cx = (obj.cx != null) ? obj.cx.floatValueX(this) : 0f;
float cy = (obj.cy != null) ? obj.cy.floatValueY(this) : 0f;
float rx = obj.rx.floatValueX(this);
float ry = obj.ry.floatValueY(this);
float left = cx - rx;
float top = cy - ry;
float right = cx + rx;
float bottom = cy + ry;
if (obj.boundingBox == null) {
obj.boundingBox = new Box(left, top, rx*2, ry*2);
}
float cpx = rx * BEZIER_ARC_FACTOR;
float cpy = ry * BEZIER_ARC_FACTOR;
Path p = new Path();
p.moveTo(cx, top);
p.cubicTo(cx+cpx, top, right, cy-cpy, right, cy);
p.cubicTo(right, cy+cpy, cx+cpx, bottom, cx, bottom);
p.cubicTo(cx-cpx, bottom, left, cy+cpy, left, cy);
p.cubicTo(left, cy-cpy, cx-cpx, top, cx, top);
p.close();
return p;
}
private void init(Context context, AttributeSet attrs) {
if (attrs != null) {
final TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.PolygonView);
final int sides = attributes.getInteger(R.styleable.PolygonView_shape_polygon_noOfSides, numberOfSides);
numberOfSides = sides > 3 ? sides : numberOfSides;
attributes.recycle();
}
super.setClipPathCreator(new ClipPathManager.ClipPathCreator() {
@Override
public Path createClipPath(int width, int height) {
final float section = (float) (2.0 * Math.PI / numberOfSides);
final int polygonSize = Math.min(width, height);
final int radius = polygonSize / 2;
final int centerX = width / 2;
final int centerY = height / 2;
final Path polygonPath = new Path();
polygonPath.moveTo((centerX + radius * (float) Math.cos(0)), (centerY + radius * (float) Math.sin(0)));
for (int i = 1; i < numberOfSides; i++) {
polygonPath.lineTo((centerX + radius * (float) Math.cos(section * i)),
(centerY + radius * (float) Math.sin(section * i)));
}
polygonPath.close();
return polygonPath;
}
@Override
public boolean requiresBitmap() {
return true;
}
});
}
private void drawLiftDown(Canvas canvas) {
Path path = new Path();
path.moveTo(0, getHeight() - roundHeight);
path.lineTo(0, getHeight());
path.lineTo(roundWidth, getHeight());
path.arcTo(new RectF(0, getHeight() - roundHeight * 2, 0 + roundWidth * 2, getHeight()), 90, 90);
path.close();
canvas.drawPath(path, paint);
}
private void drawTriangleOnly(Canvas canvas) {
Path p = new Path();
p.moveTo((float) (radius - triangle_length / 2 * Math.sqrt(3) / 3), radius - triangle_length / 2);
p.lineTo((float) (radius + triangle_length * Math.sqrt(3) / 3), radius);
p.lineTo((float) (radius - triangle_length / 2 * Math.sqrt(3) / 3), radius + triangle_length / 2);
p.close();
canvas.drawPath(p, mTrianglePaint);
}
private void drawBottomLeft(Canvas canvas) {
if ((radius[6] > 0) || (radius[7] > 0)) {
int height = getHeight();
Path path = new Path();
path.moveTo(0, height - radius[7]);
path.lineTo(0, height);
path.lineTo(radius[6], height);
path.arcTo(new RectF(0, height - 2 * radius[7],
radius[6] * 2, height), 90, 90);
path.close();
canvas.drawPath(path, roundPaint);
}
}
/**
* This requires the three points to be in a sequence that traces out a triangle in clockwise
* fashion. This is required for the triangle to be filled correctly when drawing, otherwise
* it will end up black.
*/
private static Path createTriangle(Point start, Point middle, Point end) {
Path path = new Path();
path.setFillType(Path.FillType.EVEN_ODD);
path.moveTo(start.x, start.y);
path.lineTo(middle.x, middle.y);
path.lineTo(end.x, end.y);
path.close();
return path;
}
private Path getStarPath(float centerX, float centerY, float innerRadius, float outerRadius) {
double angle = 2.0*Math.PI/10.0;
float innerTopX = innerRadius*(float)Math.sin(angle);
float innerTopY = innerRadius*(float)Math.cos(angle);
float outerTopX = outerRadius*(float)Math.sin(2f*angle);
float outerTopY = outerRadius*(float)Math.cos(2f*angle);
float innerBottomX = innerRadius*(float)Math.sin(3f*angle);
float innerBottomY = innerRadius*(float)Math.cos(3f*angle);
float outerBottomX = outerRadius*(float)Math.sin(4f*angle);
float outerBottomY = outerRadius*(float)Math.cos(4f*angle);
Path result = new Path();
result.moveTo(centerX, centerY - outerRadius);
result.lineTo(centerX + innerTopX, centerY - innerTopY);
result.lineTo(centerX + outerTopX, centerY - outerTopY);
result.lineTo(centerX + innerBottomX, centerY - innerBottomY);
result.lineTo(centerX + outerBottomX, centerY - outerBottomY);
result.lineTo(centerX, centerY + innerRadius);
result.lineTo(centerX - outerBottomX, centerY - outerBottomY);
result.lineTo(centerX - innerBottomX, centerY - innerBottomY);
result.lineTo(centerX - outerTopX, centerY - outerTopY);
result.lineTo(centerX - innerTopX, centerY - innerTopY);
result.close();
return result;
}
public void drawLabel(View view, Canvas canvas) {
if (canvas == null || view == null) {
throw new IllegalArgumentException("LabelViewHelper draw canvas or view cant't be null!");
}
canvas.save();
if (mRouteDegrees == ROTATE_LEFT){
canvas.translate(-mBgTriangleWidth / 2, 0);
canvas.rotate(mRouteDegrees, mBgTriangleWidth / 2, 0);
}else if (mRouteDegrees == ROTATE_RIGHT){
int rotateViewWH= (int) (mBgTriangleHeight * Math.sqrt(2));
canvas.translate(view.getMeasuredWidth() - rotateViewWH, -mBgTriangleHeight);
canvas.rotate(mRouteDegrees, 0, mBgTriangleHeight);
}
Path path = new Path();
path.moveTo(0, mBgTriangleHeight);
if (mTopDistance < 0) {
// mTopDistance > 0 represents a trapezoid, otherwise represents a triangle.
mTopDistance = 0;
}
path.lineTo(mBgTriangleWidth / 2 - mTopDistance, mTopDistance);
path.lineTo(mBgTriangleWidth / 2 + mTopDistance, mTopDistance);
path.lineTo(mBgTriangleWidth, mBgTriangleHeight);
path.close();
canvas.drawPath(path, mBgTrianglePaint);
if (!TextUtils.isEmpty(mTextTitle)) {
canvas.drawText(mTextTitle, (mBgTriangleWidth) / 2, mTopDistance + mTopPadding + mTextTitleRect.height(), mTextTitlePaint);
}
if (!TextUtils.isEmpty(mTextContent)) {
canvas.drawText(mTextContent, (mBgTriangleWidth) / 2, (mTopDistance + mTopPadding + mTextTitleRect.height() + mCenterPadding + mTextContentRect.height()), mTextContentPaint);
}
canvas.restore();
}
/**
* 初始化三角形指示器
*/
private void initTriangle()
{
mPath = new Path();
mTriangleHeight = (int) (mTriangleWidth / 2 / Math.sqrt(2));
mPath.moveTo(0, 0);
mPath.lineTo(mTriangleWidth, 0);
mPath.lineTo(mTriangleWidth / 2, -mTriangleHeight);
mPath.close();
}
/**
* 根据title创建tab
*/
private View generateTextView(String title, int index, int size) {
TextView tv = new TextView(getContext());
tv.setText(title);
tv.setGravity(Gravity.CENTER);
tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, tabTextSize);
LayoutParams lp;
if (margin == 0) {
lp = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
lp.width = 0;
lp.weight = 1;
} else {
lp = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);
if (index != size) {
lp.setMargins(0, 0, margin, 0);
}
}
tv.setLayoutParams(lp);
if (mLineWidth == 0) {
Rect bound = new Rect();
tv.getPaint().getTextBounds(tv.getText().toString(), 0, tv.getText().length(), bound);
mLineWidth = bound.width();
mLineWidth += 20;
mPath = new Path();
mPath.moveTo(0, 0);
mPath.lineTo(mLineWidth, 0);
mPath.lineTo(mLineWidth, lineHeight);
mPath.lineTo(0, lineHeight);
mPath.close();
}
return tv;
}
private void init(Context context, AttributeSet attrs) {
if (attrs != null) {
final TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.ArcView);
arcHeightPx = attributes.getDimensionPixelSize(R.styleable.ArcView_shape_arc_height, (int) arcHeightPx);
arcPosition = attributes.getInteger(R.styleable.ArcView_shape_arc_position, arcPosition);
attributes.recycle();
}
super.setClipPathCreator(new ClipPathManager.ClipPathCreator() {
@Override
public Path createClipPath(int width, int height) {
final Path path = new Path();
final boolean isCropInside = getCropDirection() == CROP_INSIDE;
final float arcHeightAbs = Math.abs(arcHeightPx);
switch (arcPosition) {
case POSITION_BOTTOM: {
if (isCropInside) {
path.moveTo(0, 0);
path.lineTo(0, height);
path.quadTo(width / 2, height - 2 * arcHeightAbs, width, height);
path.lineTo(width, 0);
path.close();
} else {
path.moveTo(0, 0);
path.lineTo(0, height - arcHeightAbs);
path.quadTo(width / 2, height + arcHeightAbs, width, height - arcHeightAbs);
path.lineTo(width, 0);
path.close();
}
break;
}
case POSITION_TOP:
if (isCropInside) {
path.moveTo(0, height);
path.lineTo(0, 0);
path.quadTo(width / 2, 2 * arcHeightAbs, width, 0);
path.lineTo(width, height);
path.close();
} else {
path.moveTo(0, arcHeightAbs);
path.quadTo(width / 2, -arcHeightAbs, width, arcHeightAbs);
path.lineTo(width, height);
path.lineTo(0, height);
path.close();
}
break;
case POSITION_LEFT:
if (isCropInside) {
path.moveTo(width, 0);
path.lineTo(0, 0);
path.quadTo(arcHeightAbs * 2, height / 2, 0, height);
path.lineTo(width, height);
path.close();
} else {
path.moveTo(width, 0);
path.lineTo(arcHeightAbs, 0);
path.quadTo(-arcHeightAbs, height / 2, arcHeightAbs, height);
path.lineTo(width, height);
path.close();
}
break;
case POSITION_RIGHT:
if (isCropInside) {
path.moveTo(0, 0);
path.lineTo(width, 0);
path.quadTo(width - arcHeightAbs * 2, height / 2, width, height);
path.lineTo(0, height);
path.close();
} else {
path.moveTo(0, 0);
path.lineTo(width - arcHeightAbs, 0);
path.quadTo(width + arcHeightAbs, height / 2, width - arcHeightAbs, height);
path.lineTo(0, height);
path.close();
}
break;
}
return path;
}
@Override
public boolean requiresBitmap() {
return false;
}
});
}
public void drawTextOnPath(
String text,
Path path,
float hOffset,
float vOffset,
Paint paint)
{
if (null == mMainCanvas) {
return;
}
PathMeasure pm = new PathMeasure(path, false);
Matrix matrix = new Matrix();
Path charPath = new Path();
Path textPath = new Path();
float pathLength = pm.getLength();
float coordinates[] = new float[2];
float tangent[] = new float[2];
int i = 0;
float position = hOffset;
while (i < text.length()) {
String ch = text.substring(i, i + 1);
float charWidth = paint.measureText(ch);
float nextPosition = position + charWidth;
if (nextPosition > pathLength) {
break;
}
pm.getPosTan(position + charWidth / 2, coordinates, tangent);
float rotateAngle = (float) Math.toDegrees(
Math.atan2((double) tangent[1], (double) tangent[0]));
charPath.reset();
paint.getTextPath(ch, 0, ch.length(), -charWidth / 2, vOffset, charPath);
charPath.close(); // workaround
matrix.reset();
matrix.postScale(1, -1, 0, 0);
matrix.postRotate(rotateAngle, 0, 0);
matrix.postTranslate(coordinates[0], coordinates[1]);
textPath.addPath(charPath, matrix);
++i;
position = nextPosition;
}
mMainCanvas.drawPath(textPath, paint);
// for debug
//mMainCanvas.drawTextOnPath(text, path, hOffset, vOffset, paint);
}
/**
* Draws the RadarDataSet
*
* @param c
* @param dataSet
* @param mostEntries the entry count of the dataset with the most entries
*/
protected void drawDataSet(Canvas c, IRadarDataSet dataSet, int mostEntries) {
float phaseX = mAnimator.getPhaseX();
float phaseY = mAnimator.getPhaseY();
float sliceangle = mChart.getSliceAngle();
// calculate the factor that is needed for transforming the value to
// pixels
float factor = mChart.getFactor();
MPPointF center = mChart.getCenterOffsets();
MPPointF pOut = MPPointF.getInstance(0,0);
Path surface = mDrawDataSetSurfacePathBuffer;
surface.reset();
boolean hasMovedToPoint = false;
for (int j = 0; j < dataSet.getEntryCount(); j++) {
mRenderPaint.setColor(dataSet.getColor(j));
RadarEntry e = dataSet.getEntryForIndex(j);
Utils.getPosition(
center,
(e.getY() - mChart.getYChartMin()) * factor * phaseY,
sliceangle * j * phaseX + mChart.getRotationAngle(), pOut);
if (Float.isNaN(pOut.x))
continue;
if (!hasMovedToPoint) {
surface.moveTo(pOut.x, pOut.y);
hasMovedToPoint = true;
} else
surface.lineTo(pOut.x, pOut.y);
}
if (dataSet.getEntryCount() > mostEntries) {
// if this is not the largest set, draw a line to the center before closing
surface.lineTo(center.x, center.y);
}
surface.close();
if (dataSet.isDrawFilledEnabled()) {
final Drawable drawable = dataSet.getFillDrawable();
if (drawable != null) {
drawFilledPath(c, surface, drawable);
} else {
drawFilledPath(c, surface, dataSet.getFillColor(), dataSet.getFillAlpha());
}
}
mRenderPaint.setStrokeWidth(dataSet.getLineWidth());
mRenderPaint.setStyle(Paint.Style.STROKE);
// draw the line (only if filled is disabled or alpha is below 255)
if (!dataSet.isDrawFilledEnabled() || dataSet.getFillAlpha() < 255)
c.drawPath(surface, mRenderPaint);
MPPointF.recycleInstance(center);
MPPointF.recycleInstance(pOut);
}
/**
* Draws the limit lines if there are one.
*/
private void drawLimitLines() {
ArrayList<LimitLine> limitLines = mOriginalData.getLimitLines();
if (limitLines == null)
return;
float sliceangle = getSliceAngle();
// calculate the factor that is needed for transforming the value to
// pixels
float factor = getFactor();
PointF c = getCenterOffsets();
for (int i = 0; i < limitLines.size(); i++) {
LimitLine l = limitLines.get(i);
mLimitLinePaint.setColor(l.getLineColor());
mLimitLinePaint.setPathEffect(l.getDashPathEffect());
mLimitLinePaint.setStrokeWidth(l.getLineWidth());
float r = l.getLimit() * factor;
Path limitPath = new Path();
for (int j = 0; j < mCurrentData.getXValCount(); j++) {
PointF p = getPosition(c, r, sliceangle * j + mRotationAngle);
if (j == 0)
limitPath.moveTo(p.x, p.y);
else
limitPath.lineTo(p.x, p.y);
}
limitPath.close();
mDrawCanvas.drawPath(limitPath, mLimitLinePaint);
}
}