2010-01-12 189 views

回答

40

您需要設置噴漆的對象,以填補

Paint paint = new Paint(); 
paint.setStyle(Paint.Style.FILL); 

然後,你可以畫任何你想要的,它會被填充。

canvas.drawCircle(20, 20, 15, paint); 
canvas.drawRectangle(60, 20, 15, paint); 

對於更復雜的形狀,你需要使用PATH object

93

Android沒有像Java這樣的方便的drawPolygon(x_array, y_array, numberofpoints)動作。你必須逐步製作一個Path對象。例如,爲了使一個3D地牢牆填充梯形的形狀,你可以把你所有的點在X和Y陣列然後代碼如下:

Paint wallpaint = new Paint(); 
wallpaint.setColor(Color.GRAY); 
wallpaint.setStyle(Style.FILL); 

Path wallpath = new Path(); 
wallpath.reset(); // only needed when reusing this path for a new build 
wallpath.moveTo(x[0], y[0]); // used for first point 
wallpath.lineTo(x[1], y[1]); 
wallpath.lineTo(x[2], y[2]); 
wallpath.lineTo(x[3], y[3]); 
wallpath.lineTo(x[0], y[0]); // there is a setLastPoint action but i found it not to work as expected 

canvas.drawPath(wallpath, wallpaint); 

要添加一個恆定的線性漸變對於一些深度的,你可以代碼如下。注意Y [0]被使用兩次,以保持梯度水平:

wallPaint.reset(); // precaution when resusing Paint object, here shader replaces solid GRAY anyway 
wallPaint.setShader(new LinearGradient(x[0], y[0], x[1], y[0], Color.GRAY, Color.DKGRAY,TileMode.CLAMP)); 

canvas.drawPath(wallpath, wallpaint); 

參見PaintPathCanvas文檔以獲取更多的選項,如陣列限定梯度,加入圓弧和鋪設在你的多邊形的位圖。

+10

而不是使用'Path.lineTo(X0,Y0)'你的可以簡單地調用'Path.close()'來自動添加結束線段。 – ralfoide 2013-09-28 07:33:20

2

順便說一句 - 我發現一旦你開始創建你的路徑,路徑中的任何moveTo命令都將意味着該形狀沒有填充。

當你考慮它時,Android/Java會讓形狀不填充,因爲moveTo會代表多邊形中斷。

不過,我已經看到了一些教程這樣How to draw a filled triangle in android canvas?

具有每個了lineTo後的moveTo的。儘管這可能導致多邊形不間斷,但Android會假定moveTo表示多邊形的中斷。

11

我喜歡做的三個步驟......

步驟1.創建一個尖尖類;-)

/** 
* Simple point 
*/ 
private class Point { 

    public float x = 0; 
    public float y = 0; 

    public Point(float x, float y) { 
     this.x = x; 
     this.y = y; 
    } 
} 

第2步:添加一個方法/函數用於繪製

/** 
* Draw polygon 
* 
* @param canvas The canvas to draw on 
* @param color Integer representing a fill color (see http://developer.android.com/reference/android/graphics/Color.html) 
* @param points Polygon corner points 
*/ 
private void drawPoly(Canvas canvas, int color, Point[] points) { 
    // line at minimum... 
    if (points.length < 2) { 
     return; 
    } 

    // paint 
    Paint polyPaint = new Paint(); 
    polyPaint.setColor(color); 
    polyPaint.setStyle(Style.FILL); 

    // path 
    Path polyPath = new Path(); 
    polyPath.moveTo(points[0].x, points[0].y); 
    int i, len; 
    len = points.length; 
    for (i = 0; i < len; i++) { 
     polyPath.lineTo(points[i].x, points[i].y); 
    } 
    polyPath.lineTo(points[0].x, points[0].y); 

    // draw 
    canvas.drawPath(polyPath, polyPaint); 
} 

步驟3.繪製

drawPoly(canvas, 0xFF5555ee, 
      new Point[]{ 
       new Point(10, 10), 
       new Point(15, 10), 
       new Point(15, 20) 
      }); 

是的,你可以做得更有效率,但可能沒有更多的可讀性:-)。

+7

這段代碼有一些嚴重的問題:首先在Android中已經有兩個'Point'和'PointF'類,所以你真的不需要重新創建自己的類。其次,你真的想避免在你的View.draw()方法中分配對象,並且你提供的示例爲單個繪製做了大量的分配。 – ralfoide 2013-09-28 07:35:27

+0

這取決於你想繪製多少個矩形。但我同意這不是最有效的方法。但是高效通常意味着使代碼更少可用或可讀或兩者兼而有之。 – Nux 2013-09-29 12:37:19

1

老問題,但任何人發現這一點的技巧。如果您將包含所需多邊形的字體視爲字形,則可以使用drawText函數繪製多邊形。

缺點是你必須提前知道你需要什麼樣的形狀。如果你事先知道可以包含一個漂亮的形狀庫,那就是好處。此代碼假定您的項目的assets/fonts文件夾中有一個名爲shapes的字體。

  TypeFace shapesTypeFace = Typeface.createFromAsset(getAssets(), "fonts/shapes.ttf"); 
      Paint stopSignPaint = new Paint(); 
      stopSignPaint.setColor(Color.RED); 
      //set anti-aliasing so it looks nice 
      stopSignPaint.setAntiAlias(true); 
      stopSignPaint.setTextSize(200); 
      stopSignPaint.setTypeface(shapesTypeFace); 

      //will show up as a box or question mark since 
      //the current display font doesn't have this glyph. 
      //open the shapes font in a tool like Character Map 
      //to copy and paste the glyph into your IDE 
      //saving it as a variable makes it much easier to work with 
      String hexagonGlyph = "" 
      String triangleGlyph = "" 


      ....whatever code you got... 


      //arguments: text, x coordinate, y coordinate, paint 
      canvas.drawText(hexagonGlyph, 200, 100, stopSignPaint); 

      //make it into a go sign 
      stopSignPaint.setColor(Color.Green); 
      canvas.drawText(hexagonGlyph, 200, 100, stopSignPaint); 


      //make a tiny one 
      stopSignPaint.setTextSize(20); 
      stopSignPaint.setColor(Color.RED); 
      canvas.drawText(hexagonGlyph, 200, 100, stopSignPaint); 


      //make a triangle 
      canvas.drawText(triangleGlyph, 200, 100, stopSignPaint); 
1

繪製多邊形與X邊和自定義半徑:

private void drawPolygon(Canvas mCanvas, float x, float y, float radius, float sides, float startAngle, boolean anticlockwise, Paint paint) { 

    if (sides < 3) { return; } 

    float a = ((float) Math.PI *2)/sides * (anticlockwise ? -1 : 1); 
    mCanvas.save(); 
    mCanvas.translate(x, y); 
    mCanvas.rotate(startAngle); 
    Path path = new Path(); 
    path.moveTo(radius, 0); 
    for(int i = 1; i < sides; i++) { 
     path.lineTo(radius * (float) Math.cos(a * i), radius * (float) Math.sin(a * i)); 
    } 
    path.close(); 
    mCanvas.drawPath(path, paint); 
    mCanvas.restore(); 
} 
0

試試這個,或者see the full demo

Paint paint = new Paint(); 
    paint.setColor(Color.parseColor("#BAB399")); 
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));