android如何在canvas上绘制三angular形,星形,方形,心形

我可以使用path.addCircle()和path.addRect()在canvas上绘制圆形和矩形,就像我想要触摸的一样,我可以绘制三angular形,星形,方形和心形。 我怎样才能做到这一点? 给我一个样本示例的方法。 谢谢

你必须找出数字背后的math。 三angular形和星星很容易画出来。 以下是你如何画心: http : //www.mathematische-basteleien.de/heart.htm

要绘制特殊path,您应该通过添加点,椭圆等来创build它们。canvas支持指定path的剪贴蒙版,因此您可以设置剪贴蒙版的面具,将path推送到matrix,绘制心脏的内容,然后再popup一次。

我正在做的是在andriod上实现模拟的2D页面curl效果: http : //code.google.com/p/android-page-curl/

希望这可以帮助!

对于未来的直接回答者,我使用canvas绘制了一个几乎对称的星形,如图所示:

星形图像

主要的工具是使用path。

假设你已经设置:

Paint paint = new Paint(); paint.setColor(Color.WHITE); paint.setAntiAlias(true); paint.setStyle(Paint.Style.STROKE); Path path = new Path(); 

然后在你onDraw你可以使用下面的path。 它将正确缩放到任何尺寸的canvas

 @Override protected void onDraw(Canvas canvas) { float mid = getWidth() / 2; float min = Math.min(getWidth(), getHeight()); float fat = min / 17; float half = min / 2; float rad = half - fat; mid = mid - half; paint.setStrokeWidth(fat); paint.setStyle(Paint.Style.STROKE); canvas.drawCircle(mid + half, half, rad, paint); path.reset(); paint.setStyle(Paint.Style.FILL); // top left path.moveTo(mid + half * 0.5f, half * 0.84f); // top right path.lineTo(mid + half * 1.5f, half * 0.84f); // bottom left path.lineTo(mid + half * 0.68f, half * 1.45f); // top tip path.lineTo(mid + half * 1.0f, half * 0.5f); // bottom right path.lineTo(mid + half * 1.32f, half * 1.45f); // top left path.lineTo(mid + half * 0.5f, half * 0.84f); path.close(); canvas.drawPath(path, paint); super.onDraw(canvas); } 

对于需要心脏形状的每个人来说:

  import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Style; import android.graphics.Path; import android.view.View; public class Heart extends View { private Path path; private Paint paint; public Heart(Context context) { super(context); path = new Path(); paint = new Paint(Paint.ANTI_ALIAS_FLAG); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // Fill the canvas with background color canvas.drawColor(Color.WHITE); paint.setShader(null); float width = getContext().getResources().getDimension(R.dimen.heart_width); float height = getContext().getResources().getDimension(R.dimen.heart_height); // Starting point path.moveTo(width / 2, height / 5); // Upper left path path.cubicTo(5 * width / 14, 0, 0, height / 15, width / 28, 2 * height / 5); // Lower left path path.cubicTo(width / 14, 2 * height / 3, 3 * width / 7, 5 * height / 6, width / 2, height); // Lower right path path.cubicTo(4 * width / 7, 5 * height / 6, 13 * width / 14, 2 * height / 3, 27 * width / 28, 2 * height / 5); // Upper right path path.cubicTo(width, height / 15, 9 * width / 14, 0, width / 2, height / 5); paint.setColor(Color.RED); paint.setStyle(Style.FILL); canvas.drawPath(path, paint); } } 

对不起,所有的数字,但这些最适合我:)结果如下所示:

在这里输入图像说明

这个方法将会返回一个给定宽度的正方形中给定的拐angular数量的path。 添加更多的参数来处理小半径等等。

  private Path createStarBySize(float width, int steps) { float halfWidth = width / 2.0F; float bigRadius = halfWidth; float radius = halfWidth / 2.0F; float degreesPerStep = (float) Math.toRadians(360.0F / (float) steps); float halfDegreesPerStep = degreesPerStep / 2.0F; Path ret = new Path(); ret.setFillType(FillType.EVEN_ODD); float max = (float) (2.0F* Math.PI); ret.moveTo(width, halfWidth); for (double step = 0; step < max; step += degreesPerStep) { ret.lineTo((float)(halfWidth + bigRadius * Math.cos(step)), (float)(halfWidth + bigRadius * Math.sin(step))); ret.lineTo((float)(halfWidth + radius * Math.cos(step + halfDegreesPerStep)), (float)(halfWidth + radius * Math.sin(step + halfDegreesPerStep))); } ret.close(); return ret; } 

除了椭圆和矩形之外,您还需要这两个(至less):

drawLine(float startX,float startY,float stopX,float stopY,Paint paint)
drawLines(float [] pts,int offset,int count,Paint paint)

例如: 如何在android中绘制一条线

canvas上的文档: http : //developer.android.com/reference/android/graphics/Canvas.html

如果您需要在广场内画一颗星星,可以使用下面的代码。

posXposY是包围星星的尖端的正方形的左上angular的坐标(正方形实际上没有绘制)。

size是广场的宽度和高度。

a是明星的顶尖。 path是顺时针创build的。

这绝不是一个完美的解决scheme,但它可以很快完成工作。

  public void drawStar(float posX, float posY, int size, Canvas canvas){ int hMargin = size/9; int vMargin = size/4; Point a = new Point((int) (posX + size/2), (int) posY); Point b = new Point((int) (posX + size/2 + hMargin), (int) (posY + vMargin)); Point c = new Point((int) (posX + size), (int) (posY + vMargin)); Point d = new Point((int) (posX + size/2 + 2*hMargin), (int) (posY + size/2 + vMargin/2)); Point e = new Point((int) (posX + size/2 + 3*hMargin), (int) (posY + size)); Point f = new Point((int) (posX + size/2), (int) (posY + size - vMargin)); Point g = new Point((int) (posX + size/2 - 3*hMargin), (int) (posY + size)); Point h = new Point((int) (posX + size/2 - 2*hMargin), (int) (posY + size/2 + vMargin/2)); Point i = new Point((int) posX, (int) (posY + vMargin)); Point j = new Point((int) (posX + size/2 - hMargin), (int) (posY + vMargin)); Path path = new Path(); path.moveTo(ax, ay); path.lineTo(bx, by); path.lineTo(cx, cy); path.lineTo(dx, dy); path.lineTo(ex, ey); path.lineTo(fx, fy); path.lineTo(fx, fy); path.lineTo(gx, gy); path.lineTo(hx, hy); path.lineTo(ix, iy); path.lineTo(jx, jy); path.lineTo(ax, ay); path.close(); canvas.drawPath(path, paint); } 

它很好用的Shape类的实例))

  @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); HeartShape shape = new HeartShape(); ShapeDrawable shapeDrawable = new ShapeDrawable(shape); shapeDrawable.setColorFilter(new LightingColorFilter(0, Color.BLUE)); LinearLayout linearLayout = new LinearLayout(this); linearLayout.setLayoutParams(new LinearLayout.LayoutParams(350 * 3, 350 * 3)); linearLayout.setBackground(shapeDrawable); setContentView(linearLayout); } 

创build一个渲染好心的形状类

  public class HeartShape extends Shape { private final int INVALID_SIZE = -1; private Path mPath = new Path(); private RectF mRectF = new RectF(); private float mOldWidth = INVALID_SIZE; private float mOldHeight = INVALID_SIZE; private float mScaleX, mScaleY; public HeartShape() { } @Override public void draw(Canvas canvas, Paint paint) { canvas.save(); canvas.scale(mScaleX, mScaleY); float width = mRectF.width(); float height = mRectF.height(); float halfWidth = width/2; float halfHeight = height/2; float stdDestX = 5 * width / 14; float stdDestY = 2 * height / 3; PointF point1 = new PointF(stdDestX, 0); PointF point2 = new PointF(0, height / 15); PointF point3 = new PointF(stdDestX / 5, stdDestY); PointF point4 = new PointF(stdDestX, stdDestY); // Starting point mPath.moveTo(halfWidth, height / 5); mPath.cubicTo(point1.x, point1.y, point2.x, point2.y, width / 28, 2 * height / 5); mPath.cubicTo(point3.x, point3.y, point4.x, point4.y, halfWidth, height); canvas.drawPath(mPath, paint); canvas.scale(-mScaleX, mScaleY, halfWidth, halfHeight); canvas.drawPath(mPath, paint); canvas.restore(); } @Override protected void onResize(float width, float height) { mOldWidth = mOldWidth == INVALID_SIZE ? width : Math.max(1, mOldWidth); mOldHeight = mOldHeight == INVALID_SIZE ? height : Math.max(1, mOldHeight); width = Math.max(1, width); height = Math.max(1, height); mScaleX = width / mOldWidth; mScaleY = height / mOldHeight; mOldWidth = width; mOldHeight = height; mRectF.set(0, 0, width, height); } @Override public void getOutline(@NonNull Outline outline) { // HeartShape not supported outlines } @Override public HeartShape clone() throws CloneNotSupportedException { HeartShape shape = (HeartShape) super.clone(); shape.mPath = new Path(mPath); return shape; } } 

在这里输入图像说明