下面列出了android.graphics.Path#rewind ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@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);
}
@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);
}
@Override
public void draw(Canvas canvas, Paint paint) {
float width = getWidth();
float height = getHeight();
float size = Math.min(width, height);
int radius = (int) (size * 38f / 48f / 2f + 0.5f);
paint.setStrokeWidth(size / 48f * 4f);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.WHITE);
canvas.drawCircle(width / 2f, height / 2f, radius, paint);
paint.setStyle(Paint.Style.FILL);
Path path = this.path;
float side = size / 48f * 16f;
float altitude = (float) (side * Math.sqrt(3f) / 2f);
path.moveTo(width / 2f + altitude * 2f / 3f, height / 2f);
path.lineTo(width / 2f - altitude / 3f, height / 2f - side / 2f);
path.lineTo(width / 2f - altitude / 3f, height / 2f + side / 2f);
path.close();
canvas.drawPath(path, paint);
path.rewind();
}
private void updatePath() {
final Path path = mPath;
path.rewind();
final ArrayList<PointF> points = mPoints;
final int count = points.size();
if (count <= 1)
return;
float preX = 0;
float preY = 0;
for (int i = 0; i < count; i++) {
final float x = points.get(i).x;
final float y = points.get(i).y;
if (i == 0) {
path.moveTo(x, y);
preX = x;
preY = y;
} else {
path.quadTo(preX, preY, (x + preX) / 2, (y + preY) / 2);
preX = x;
preY = y;
}
}
}
@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);
}
static void inRect(@NonNull Path into, @NonNull float[] pathData) {
if (!into.isEmpty()) into.rewind();
into.moveTo(pathData[0], pathData[1]); // top left
into.lineTo(pathData[2], pathData[3]); // top right
into.lineTo(pathData[4], pathData[5]); // bottom right
into.lineTo(pathData[6], pathData[7]); // bottom left
}
/**
* Writes the given {@link ShapeAppearanceModel} to {@code path}
*
* @param shapeAppearanceModel The shape to be applied in the path.
* @param interpolation the desired interpolation.
* @param bounds the desired bounds for the path.
* @param pathListener the path
* @param path the returned path out-var.
*/
@RestrictTo(Scope.LIBRARY_GROUP)
public void calculatePath(
ShapeAppearanceModel shapeAppearanceModel,
float interpolation,
RectF bounds,
PathListener pathListener,
@NonNull Path path) {
path.rewind();
overlappedEdgePath.rewind();
boundsPath.rewind();
boundsPath.addRect(bounds, Direction.CW);
ShapeAppearancePathSpec spec =
new ShapeAppearancePathSpec(
shapeAppearanceModel, interpolation, bounds, pathListener, path);
// Calculate the transformations (rotations and translations) necessary for each edge and
// corner treatment.
for (int index = 0; index < 4; index++) {
setCornerPathAndTransform(spec, index);
setEdgePathAndTransform(index);
}
for (int index = 0; index < 4; index++) {
appendCornerPath(spec, index);
appendEdgePath(spec, index);
}
path.close();
overlappedEdgePath.close();
// Union with the edge paths that had an intersection to handle overlaps.
if (VERSION.SDK_INT >= VERSION_CODES.KITKAT && !overlappedEdgePath.isEmpty()) {
path.op(overlappedEdgePath, Op.UNION);
}
}
@Override
public void setBounds(int left, int top, int right, int bottom) {
Rect bounds = getBounds();
if (bounds.left != left || bounds.top != top || bounds.right != right || bounds.bottom != bottom) {
Path path = this.path;
path.rewind();
float radius = this.radius;
float shift = ((float) Math.sqrt(2) - 1f) * radius * 4f / 3f;
path.moveTo(left, top);
path.rLineTo(radius, 0);
path.rCubicTo(-shift, 0, -radius, radius - shift, -radius, radius);
path.close();
path.moveTo(right, top);
path.rLineTo(-radius, 0);
path.rCubicTo(shift, 0, radius, radius - shift, radius, radius);
path.close();
path.moveTo(left, bottom);
path.rLineTo(radius, 0);
path.rCubicTo(-shift, 0, -radius, shift - radius, -radius, -radius);
path.close();
path.moveTo(right, bottom);
path.rLineTo(-radius, 0);
path.rCubicTo(shift, 0, radius, shift - radius, radius, -radius);
path.close();
}
super.setBounds(left, top, right, bottom);
}
private synchronized static Path createPathFromPool() {
if (!pathPool.isEmpty()) {
Path out = pathPool.remove(pathPool.size()-1);
out.rewind();
return out;
}
return new Path();
}
/**
* Draws a corner shadow on the canvas in the current bounds with the matrix transform applied.
*/
public void drawCornerShadow(
@NonNull Canvas canvas,
@Nullable Matrix matrix,
@NonNull RectF bounds,
int elevation,
float startAngle,
float sweepAngle) {
boolean drawShadowInsideBounds = sweepAngle < 0;
Path arcBounds = scratch;
if (drawShadowInsideBounds) {
cornerColors[0] = 0;
cornerColors[1] = shadowEndColor;
cornerColors[2] = shadowMiddleColor;
cornerColors[3] = shadowStartColor;
} else {
// Calculate the arc bounds to prevent drawing shadow in the same part of the arc.
arcBounds.rewind();
arcBounds.moveTo(bounds.centerX(), bounds.centerY());
arcBounds.arcTo(bounds, startAngle, sweepAngle);
arcBounds.close();
bounds.inset(-elevation, -elevation);
cornerColors[0] = 0;
cornerColors[1] = shadowStartColor;
cornerColors[2] = shadowMiddleColor;
cornerColors[3] = shadowEndColor;
}
float startRatio = 1f - (elevation / (bounds.width() / 2f));
float midRatio = startRatio + ((1f - startRatio) / 2f);
cornerPositions[1] = startRatio;
cornerPositions[2] = midRatio;
cornerShadowPaint.setShader(
new RadialGradient(
bounds.centerX(),
bounds.centerY(),
bounds.width() / 2,
cornerColors,
cornerPositions,
Shader.TileMode.CLAMP));
// TODO(b/117606382): handle oval bounds by scaling the canvas.
canvas.save();
canvas.concat(matrix);
if (!drawShadowInsideBounds) {
canvas.clipPath(arcBounds, Op.DIFFERENCE);
// This line is required for the next drawArc to work correctly, I think.
canvas.drawPath(arcBounds, transparentPaint);
}
canvas.drawArc(bounds, startAngle, sweepAngle, true, cornerShadowPaint);
canvas.restore();
}