2010-01-12 35 views

risposta

40

è necessario impostare l'oggetto vernice per riempire

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

Quindi è possibile disegnare quello che vuoi, e sarà riempito.

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

ecc

Per forme più complesse è necessario utilizzare il PATH object.

93

Android non ha una pratica azione drawPolygon(x_array, y_array, numberofpoints) come Java. Devi passare attraverso la creazione di un oggetto Path punto per punto. Ad esempio, per fare una forma trapezoidale pieno per un muro sotterraneo in 3D, si potrebbe mettere tutti i punti in X e Y array poi codice come segue:

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); 

Per aggiungere una sfumatura lineare costante per una certa profondità, si potrebbe codice come segue. Nota y [0] è usato due volte per mantenere il gradiente orizzontale:

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); 

Fare riferimento alla Paint, Path e Canvas documentazione per altre opzioni, come matrice definita gradienti, aggiungendo archi e posa un bitmap sopra poligono.

+10

Invece di utilizzare 'Path.lineTo (x0, y0)' voi può semplicemente chiamare 'Path.close()' per aggiungere automaticamente il segmento della linea di chiusura. – ralfoide

2

BTW - Ho scoperto che una volta che si inizia a creare il percorso, qualsiasi comando moveTo all'interno del percorso significherà che la forma è lasciata vuota.

Ha senso quando ci si pensa, che Android/Java lascerebbe la forma vuota come lo spostamento. Rappresenterebbe un'interruzione nel poligono.

Comunque ho visto alcuni tutorial come questo How to draw a filled triangle in android canvas?

che hanno moveTo del dopo ogni lineTo. Anche se ciò potrebbe comportare un poligono ininterrotto, Android presuppone che un moveTo rappresenti un'interruzione nel poligono.

11

mi piace farlo in tre fasi ...

Fase 1. Creare una classe a punta ;-)

/** 
* 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; 
    } 
} 

Fase 2. Aggiungere un metodo/funzione per disegnare

/** 
* 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); 
} 

Fase 3. Draw

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

Sì, si potrebbe probabilmente farlo in modo più efficiente, ma probabilmente non molto più leggibile :-).

+7

Questo codice ha alcuni problemi gravi: in primo luogo ci sono già due classi 'Point' e' PointF' in Android, quindi non è necessario reinventare le proprie. In secondo luogo, si vuole davvero evitare di allocare oggetti nei propri metodi View.draw() e l'esempio fornito fornisce tonnellate di allocazioni per un singolo progetto. – ralfoide

+0

Dipende da quanti rettangoli si desidera disegnare. Ma sono d'accordo che questo non è il modo più efficiente per farlo. Ma essere efficienti di solito significa rendere il codice meno utilizzabile o leggibile o entrambi. – Nux

1

Vecchia domanda, ma un trucco per chiunque lo trovi. Se si include un carattere con il poligono desiderato come un glifo, è possibile utilizzare la funzione drawText per disegnare il poligono.

Il rovescio della medaglia è che devi sapere in anticipo quali forme ti serviranno.Il lato positivo è che se lo sai in anticipo puoi includere una bella libreria di forme. Questo codice presuppone che tu abbia un font chiamato shape nella tua cartella assets/fonts del tuo progetto.

  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

Disegna Poligono con x lati e raggio personalizzato:

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

Prova questa, o see the full demo

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