下面列出了怎么用android.graphics.Path的API类实例代码及写法,或者点击链接到github查看源代码。
public SimpleTagImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SimpleTagImageView, defStyleAttr, 0);
mTagOrientation = a.getInteger(R.styleable.SimpleTagImageView_simple_tag_orientation, 0);
mTagWidth = a.getDimensionPixelSize(R.styleable.SimpleTagImageView_simple_tag_width, DimenUtils.dpToPxInt(DEFAULT_TAG_WIDTH));
mCornerDistance = a.getDimensionPixelSize(R.styleable.SimpleTagImageView_simple_corner_distance, DimenUtils.dpToPxInt(DEFAULT_CORNER_DISTANCE));
mTagBackgroundColor = a.getColor(R.styleable.SimpleTagImageView_simple_tag_background_color, DEFAULT_TAG_BACKGROUND_COLOR);
mTagText = a.getString(R.styleable.SimpleTagImageView_simple_tag_text);
mTagTextSize = a.getDimensionPixelSize(R.styleable.SimpleTagImageView_simple_tag_textSize, DimenUtils.dpToPxInt(DEFAULT_TAG_TEXT_SIZE));
mTagTextColor = a.getColor(R.styleable.SimpleTagImageView_simple_tag_textColor, DEFAULT_TAG_TEXT_COLOR);
mTagEnable = a.getBoolean(R.styleable.SimpleTagImageView_simple_tag_enable, true);
mRoundRadius = a.getDimensionPixelSize(R.styleable.SimpleTagImageView_simple_tag_round_radius, 0);
a.recycle();
if (TextUtils.isEmpty(mTagText)) mTagText = "";
mPaint = new Paint();
mPath = new Path();
mTextPaint = new Paint();
mTagTextBound = new Rect();
startPoint = new MyPoint();
endPoint = new MyPoint();
mRoundRect = new RectF();
}
private void drawCloud(Canvas canvas) {
mPath.reset();
mPaint.setShader(mCloudLinearGradient);
if (mCircleInfoBottomOne.isCanDraw())
mPath.addCircle(mCircleInfoBottomOne.getX(),mCircleInfoBottomOne.getY(),mCircleInfoBottomOne.getRadius(), Path.Direction.CW);//左下1
if (mCircleInfoBottomTwo.isCanDraw())
mPath.addCircle(mCircleInfoBottomTwo.getX(),mCircleInfoBottomTwo.getY(),mCircleInfoBottomTwo.getRadius(), Path.Direction.CW);//底部2
if (mCircleInfoBottomThree.isCanDraw())
mPath.addCircle(mCircleInfoBottomThree.getX(),mCircleInfoBottomThree.getY(),mCircleInfoBottomThree.getRadius(), Path.Direction.CW);//底3
if (mCircleInfoTopOne.isCanDraw())
mPath.addCircle(mCircleInfoTopOne.getX(),mCircleInfoTopOne.getY(),mCircleInfoTopOne.getRadius(), Path.Direction.CW);//顶1
if (mCircleInfoTopTwo.isCanDraw())
mPath.addCircle(mCircleInfoTopTwo.getX(),mCircleInfoTopTwo.getY(),mCircleInfoTopTwo.getRadius(), Path.Direction.CW);//顶2
canvas.save();
canvas.clipRect(0,0,getMeasuredWidth(),getMeasuredHeight()/2+getMeasuredWidth()/7f);
canvas.drawPath(mPath,mPaint);
canvas.restore();
mPaint.setShader(null);
}
/**
* 绘制圆角控件. 修复使用clipPath有锯齿问题.
*/
private void drawShapePathCanvas(Canvas shapeCanvas) {
if (shapeCanvas != null) {
int width = getWidth();
int height = getHeight();
if (width == 0 || height == 0)
return;
int count = shapeCanvas.save();
int count2 = shapeCanvas.saveLayer(0, 0, width, height, null, Canvas.ALL_SAVE_FLAG);
//
Path path = getShapePath(width, height, mRadius);
super.draw(shapeCanvas);
shapeCanvas.drawPath(path, mShapePaint);
//
if (count2 > 0) {
shapeCanvas.restoreToCount(count2);
}
shapeCanvas.restoreToCount(count);
}
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
// Draws a highlighted path to indicate the current progress to meet size requirement.
float sizeProgress = PreferenceUtils.getProgressToMeetBarcodeSizeRequirement(overlay, barcode);
Path path = new Path();
if (sizeProgress > 0.95f) {
// To have a completed path with all corners rounded.
path.moveTo(boxRect.left, boxRect.top);
path.lineTo(boxRect.right, boxRect.top);
path.lineTo(boxRect.right, boxRect.bottom);
path.lineTo(boxRect.left, boxRect.bottom);
path.close();
} else {
path.moveTo(boxRect.left, boxRect.top + boxRect.height() * sizeProgress);
path.lineTo(boxRect.left, boxRect.top);
path.lineTo(boxRect.left + boxRect.width() * sizeProgress, boxRect.top);
path.moveTo(boxRect.right, boxRect.bottom - boxRect.height() * sizeProgress);
path.lineTo(boxRect.right, boxRect.bottom);
path.lineTo(boxRect.right - boxRect.width() * sizeProgress, boxRect.bottom);
}
canvas.drawPath(path, pathPaint);
}
@Override
protected void onDraw(final Canvas canvas) {
super.onDraw(canvas);
final int layoutDirection = ViewCompat.getLayoutDirection(this);
final int width = getWidth();
final int height = getHeight();
final float halfHeight = height / 2.0f;
final Path path = mIndicatorPath;
path.rewind();
if (layoutDirection == ViewCompat.LAYOUT_DIRECTION_RTL) {
// Left arrow
path.moveTo(width, 0.0f);
path.lineTo(0.0f, halfHeight);
path.lineTo(width, height);
} else { // LAYOUT_DIRECTION_LTR
// Right arrow
path.moveTo(0.0f, 0.0f);
path.lineTo(width, halfHeight);
path.lineTo(0.0f, height);
}
path.close();
final int[] stateSet = getDrawableState();
final int color = mIndicatorColor.getColorForState(stateSet, 0);
mIndicatorPaint.setColor(color);
canvas.drawPath(path, mIndicatorPaint);
}
PathInfo(Path path, float width, float height) {
this.path = path;
float tmpWidth = width;
float tmpHeight = height;
RectF bounds = new RectF();
path.computeBounds(bounds, true);
if(width <= 0 && height <= 0) {
tmpWidth = (float) Math.ceil(bounds.width());
tmpHeight = (float) Math.ceil(bounds.height());
path.offset(-1 * (float) Math.floor(bounds.left),
-1 * (float) Math.round(bounds.top));
}
this.width = tmpWidth;
this.height = tmpHeight;
}
/**
* 绘制倒影.
*/
public void drawReflection(Canvas reflectionCanvas) {
int width = getWidth();
int height = getHeight();
int count = reflectionCanvas.save();
int count2 = reflectionCanvas.saveLayer(0, 0, width, mRefHeight, null, Canvas.ALL_SAVE_FLAG);
//
reflectionCanvas.save();
reflectionCanvas.clipRect(0, 0, getWidth(), mRefHeight);
reflectionCanvas.save();
reflectionCanvas.scale(1, -1);
reflectionCanvas.translate(0, -getHeight());
super.draw(reflectionCanvas);
if (mIsDrawShape) {
Path path = getShapePath(width, height, mRadius);
reflectionCanvas.drawPath(path, mShapePaint);
}
reflectionCanvas.restore();
reflectionCanvas.drawRect(0, 0, getWidth(), mRefHeight, mRefPaint);
reflectionCanvas.restore();
//
if (count2 > 0) {
reflectionCanvas.restoreToCount(count2);
}
reflectionCanvas.restoreToCount(count);
}
private void addObjectToClip(SVG.Use obj, Path combinedPath, Matrix combinedPathMatrix)
{
updateStyleForElement(state, obj);
if (!display())
return;
if (!visible())
return;
if (obj.transform != null)
combinedPathMatrix.preConcat(obj.transform);
// Locate the referenced object
SVG.SvgObject ref = obj.document.resolveIRI(obj.href);
if (ref == null) {
error("Use reference '%s' not found", obj.href);
return;
}
checkForClipPath(obj);
addObjectToClip(ref, false, combinedPath, combinedPathMatrix);
}
@Override protected void onDraw(Canvas canvas) {
if (width >= 12 && height > 12)
{
Path path = new Path(); //四个圆角
path.moveTo(12, 0);
path.lineTo(width - 12, 0);
path.quadTo(width, 0, width, 12);
path.lineTo(width, height - 12);
path.quadTo(width, height, width - 12, height);
path.lineTo(12, height);
path.quadTo(0, height, 0, height - 12);
path.lineTo(0, 12);
path.quadTo(0, 0, 12, 0);
canvas.clipPath(path); }
super.onDraw(canvas);
}
public TextSticker(Context context, String text, int viewGroupCenterX, int viewGroupCenterY) {
super(context);
this.text = text;
if (TextUtils.isEmpty(this.text)) {
this.text = context.getString(R.string.text_sticker_hint_easy_photos);
}
path = new Path();
textLayoutWidth = getResources().getDisplayMetrics().widthPixels / 2;
initButtons();
initPaints();
resetSize();
initStartPoint(viewGroupCenterX, viewGroupCenterY);
initPs();
resetBitmap();
initMatrix();
initCanvasPosition();
lastDegree = computeDegree(new Point((int) textWidth, (int) textHeight), new Point((int) textWidth / 2, (int) textHeight / 2));
lastDoubleDegress = 1000;
gestureDetector = new GestureDetector(context, new StickerGestureListener());
}
protected RatioKeyline(DisplayMetrics metrics) {
mTempRect = new Rect();
mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBackgroundPaint.setStyle(Paint.Style.FILL);
mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
mLabelPath = new Path();
// Hard-coded defaults
mTextPaint.setTextSize((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_TEXT_SIZE, metrics));
// Make default keyline path
mLabelHeight = (int) ((DEFAULT_LABEL_HEIGHT) * metrics.density);
mLabelRectWidth = mLabelHeight * 2;
mLabelSideWidth = mLabelHeight * 3 / 4;
mLabelPath.rLineTo(0, -mLabelHeight);
mLabelPath.rLineTo(-mLabelRectWidth, 0);
mLabelPath.rLineTo(-mLabelSideWidth, mLabelHeight);
mLabelPath.close();
}
TrailedShape(float multiplier) {
this.mMultiplier = multiplier;
// Setup trail variables
this.mTrailPath = new Path();
this.mTrailList = new LinkedList<>();
// Setup paint and attributes
this.mPaint = new Paint();
this.mTrailPaint = new Paint();
mPaint.setStyle(Paint.Style.FILL);
mTrailPaint.setStyle(Paint.Style.STROKE);
mTrailPaint.setStrokeWidth(5);
mTrailPaint.setStrokeJoin(Paint.Join.ROUND);
mTrailPaint.setStrokeCap(Paint.Cap.ROUND);
}
public void createConvexHull()
{
UPath up = new UPath();
for(List<UPath>lup : letterupaths)
{
for (UPath upx : lup)
up.subPaths.addAll(upx.subPaths);
}
USubPath uspch = up.convexHull();
Path bez = uspch.bezierPath();
bez.close();
hotPath = new OBPath(bez);
int col = Color.argb((int)(0.7*255),255,0,0);
hotPath.setFillColor(col);
hotPath.setStrokeColor(col);
hotPath.setLineWidth(applyGraphicScale(paths.get(0).lineWidth() ));
hotPath.setLineJoin(OBStroke.kCALineJoinRound);
hotPath.sizeToBoundingBoxIncludingStroke();
hotPath.setZPosition(100);
//attachControl(hotPath);
}
@Nullable
public static <T> PathAnimatorCompat ofPointF(@Nullable T target, @Nullable PointFProperty<T> property, @Nullable Path path) {
PathAnimatorCompat animator = null;
if (target != null && property != null && path != null) {
animator = new PathAnimatorCompat(target, property);
animator.mPathMeasure = new PathMeasure(path, false);
animator.mPathLength = animator.mPathMeasure.getLength();
}
return animator;
}
@NonNull
public static <T> ObjectAnimator ofInt(@Nullable T target,
@NonNull Property<T, Integer> xProperty,
@NonNull Property<T, Integer> yProperty,
@NonNull Path path) {
return ObjectAnimator.ofInt(target, xProperty, yProperty, path);
}
public InkPageIndicator(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
final int density = (int) context.getResources().getDisplayMetrics().density;
// Load attributes
final TypedArray a = getContext().obtainStyledAttributes(
attrs, R.styleable.InkPageIndicator, defStyle, 0);
dotDiameter = a.getDimensionPixelSize(R.styleable.InkPageIndicator_dotDiameter,
DEFAULT_DOT_SIZE * density);
dotRadius = dotDiameter / 2;
halfDotRadius = dotRadius / 2;
gap = a.getDimensionPixelSize(R.styleable.InkPageIndicator_dotGap,
DEFAULT_GAP * density);
animDuration = (long) a.getInteger(R.styleable.InkPageIndicator_animationDuration,
DEFAULT_ANIM_DURATION);
animHalfDuration = animDuration / 2;
unselectedColour = a.getColor(R.styleable.InkPageIndicator_pageIndicatorColor,
DEFAULT_UNSELECTED_COLOUR);
selectedColour = a.getColor(R.styleable.InkPageIndicator_currentPageIndicatorColor,
DEFAULT_SELECTED_COLOUR);
a.recycle();
unselectedPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
unselectedPaint.setColor(unselectedColour);
selectedPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
selectedPaint.setColor(selectedColour);
interpolator = AnimUtils.getFastOutSlowInInterpolator(context);
// create paths & rect now – reuse & rewind later
combinedUnselectedPath = new Path();
unselectedDotPath = new Path();
unselectedDotLeftPath = new Path();
unselectedDotRightPath = new Path();
rectF = new RectF();
addOnAttachStateChangeListener(this);
}
@Override public Path getPath() {
if (isPathValid) {
return path;
}
path.reset();
PointF size = sizeAnimation.getValue();
float halfWidth = size.x / 2f;
float halfHeight = size.y / 2f;
// TODO: handle bounds
float cpW = halfWidth * ELLIPSE_CONTROL_POINT_PERCENTAGE;
float cpH = halfHeight * ELLIPSE_CONTROL_POINT_PERCENTAGE;
path.reset();
path.moveTo(0, -halfHeight);
path.cubicTo(0 + cpW, -halfHeight, halfWidth, 0 - cpH, halfWidth, 0);
path.cubicTo(halfWidth, 0 + cpH, 0 + cpW, halfHeight, 0, halfHeight);
path.cubicTo(0 - cpW, halfHeight, -halfWidth, 0 + cpH, -halfWidth, 0);
path.cubicTo(-halfWidth, 0 - cpH, 0 - cpW, -halfHeight, 0, -halfHeight);
PointF position = positionAnimation.getValue();
path.offset(position.x, position.y);
path.close();
Utils.applyTrimPathIfNeeded(path, trimPath);
isPathValid = true;
return path;
}
public AdditiveAnimation(T target, String tag, float startValue, Path path, PathEvaluator.PathMode pathMode, PathEvaluator sharedEvaluator) {
mTarget = target;
mStartValue = startValue;
mPath = path;
mSharedPathEvaluator = sharedEvaluator;
mPathMode = pathMode;
mTargetValue = evaluateAt(1f);
setTag(tag);
}
private void drawTopLeft(Canvas canvas) {
if (topLeftRadius > 0) {
Path path = new Path();
path.moveTo(0, topLeftRadius);
path.lineTo(0, 0);
path.lineTo(topLeftRadius, 0);
path.arcTo(new RectF(0, 0, topLeftRadius * 2, topLeftRadius * 2),
-90, -90);
path.close();
canvas.drawPath(path, roundPaint);
}
}
public void drawHighlightCircle(Canvas c,
MPPointF point,
float innerRadius,
float outerRadius,
int fillColor,
int strokeColor,
float strokeWidth) {
c.save();
outerRadius = Utils.convertDpToPixel(outerRadius);
innerRadius = Utils.convertDpToPixel(innerRadius);
if (fillColor != ColorTemplate.COLOR_NONE) {
Path p = mDrawHighlightCirclePathBuffer;
p.reset();
p.addCircle(point.x, point.y, outerRadius, Path.Direction.CW);
if (innerRadius > 0.f) {
p.addCircle(point.x, point.y, innerRadius, Path.Direction.CCW);
}
mHighlightCirclePaint.setColor(fillColor);
mHighlightCirclePaint.setStyle(Paint.Style.FILL);
c.drawPath(p, mHighlightCirclePaint);
}
if (strokeColor != ColorTemplate.COLOR_NONE) {
mHighlightCirclePaint.setColor(strokeColor);
mHighlightCirclePaint.setStyle(Paint.Style.STROKE);
mHighlightCirclePaint.setStrokeWidth(Utils.convertDpToPixel(strokeWidth));
c.drawCircle(point.x, point.y, outerRadius, mHighlightCirclePaint);
}
c.restore();
}
public BottlePath() {
mBottlePath = new Path();
mBeerPath = new Path();
mLabelOuterCirclePath = new Path();
mLabelInnerCirclePath = new Path();
mLabelRibbonPath = new Path();
mEmptyPath = new Path();
}
@Override public Path getPath() {
path.reset();
if (mergePaths.isHidden()) {
return path;
}
switch (mergePaths.getMode()) {
case MERGE:
addPaths();
break;
case ADD:
opFirstPathWithRest(Path.Op.UNION);
break;
case SUBTRACT:
opFirstPathWithRest(Path.Op.REVERSE_DIFFERENCE);
break;
case INTERSECT:
opFirstPathWithRest(Path.Op.INTERSECT);
break;
case EXCLUDE_INTERSECTIONS:
opFirstPathWithRest(Path.Op.XOR);
break;
}
return path;
}
@Override
protected void onDraw(Canvas canvas) {
//super.onDraw(canvas);
canvas.save();
canvas.translate(0,-Ui.cd.getHt(10));
canvas.save();
bass.draw(canvas);
float radius = 10;
final RectF oval = new RectF();
oval.set(0, 0, bass.width, bass.height);
Path ph = new Path();
ph.setFillType(Path.FillType.WINDING);
ph.moveTo(bass.width/2, bass.width/2);
if(angle > 110 - 1){
ph.addArc(oval,-(200) + 110,angle - 110);
}else{
ph.addArc(oval,-(90) - (110 - angle),(110 - angle));
}
ph.lineTo(bass.width/2,bass.width/2);
canvas.clipPath(ph);
basstop.draw(canvas);
canvas.restore();
canvas.save();
canvas.rotate(-(90+20),XX,YY);
canvas.rotate(angle,XX,YY);
bassdot.draw(canvas);
canvas.restore();
int val = (angle - 110);
val = (int) ((100f / 110) * val);
levelText.setText(val+"",true);
levelText.draw(canvas);
canvas.restore();
super.drawShape(canvas);
//canvas.drawPath(ph,bass.img.maskPaint);
}
public Path getGeneralPath() {
// precompute cosine and sine of angle
double cot = cos(theta);
double sit = sin(theta);
// create new path
Path path = new Path();
// move to the first point
path.moveTo((float) (xc + r1 * cot), (float) (yc + r1 * sit));
// return path after adding curve
return this.appendPath(path);
}
/**
* Draws the grid line at the specified position using the provided path.
*
* @param c
* @param x
* @param y
* @param gridLinePath
*/
protected void drawGridLine(Canvas c, float x, float y, Path gridLinePath) {
gridLinePath.moveTo(x, mViewPortHandler.contentBottom());
gridLinePath.lineTo(x, mViewPortHandler.contentTop());
// draw a path because lines don't support dashing on lower android versions
c.drawPath(gridLinePath, mGridPaint);
gridLinePath.reset();
}
/**
* Return the actual bounding box of the graphics without transformation
*
* @return
*/
public RectF getOuterBoundingBox() {
if (boundingBox != null) {
Path path = new Path();
path.addRect(boundingBox, Path.Direction.CW);
path.transform(getDisplayMatrix());
RectF box = new RectF();
path.computeBounds(box, true);
return box;
}
return new RectF();
}
private void initPathMeasure()
{
mMusicDrawPaths = new LinkedList<>();
// 五线谱
for (int i = 0; i < MUSIC_LINE_COUNT; i++)
{
Path drawPath = new Path();
mMusicDrawPaths.add(drawPath);
}
mPathMeasure = new PathMeasure();
}
void createCollar()
{
OBControl obja1 = objectDict.get("obja1");
float w = obja1.width() + graphicScale() * 20;
float radius = w/2;
Path p = new Path();
p.addCircle(radius,radius,radius,Path.Direction.CCW);
OBPath obp = new OBPath(p,w,w,0f,0f);
obp.setFillColor(Color.LTGRAY);
attachControl(obp);
objectDict.put("collar",obp);
obp.setZPosition(-0.1f);
obp.hide();
}
public
@NonNull
Path getContentPath(@NonNull RectF borderBox) {
Path contentClip = new Path();
prepareBorderPath(0, 0, 0, 0, borderBox, contentClip);
return contentClip;
}
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;
}