2017-09-26 5 views
1

J'ai un bouton que je veux dessiner un rectangle coin arrondi autour d'elle progressivement après je l'ai cliqué. J'essaie de dessiner des courbes de Bézier dans une toile mais je n'ai pas trouvé la formule d'une courbe de Bézier qui pourrait peindre un rectangle de coin arrondi. Je finis donc par dessiner quatre lignes droites pour créer un rectangle sans coins arrondis. Voici le code relatif:Comment dessiner un rectangle coin arrondi progressivement avec de la toile

public class CustomProgressBar extends View{ 

private Paint paint = new Paint(); 
public HomeFragment mHomeFragment; 
private Context context; 
private Path path; 
int width = 178; 
int height = 58; 
int x1=0; 
int y1=0; 
int x2=width; 
int y2=0; 
int x3=width; 
int y3=height; 
int x4=0; 
int y4=height; 
int currentLine=0; 
int stepLength = 8; 

public CustomProgressBar(Context context) { 
    super(context); 

} 

public CustomProgressBar(Context context, AttributeSet attrs) { 

    super(context, attrs); 
    this.context = context; 
} 

public CustomProgressBar(Context context, AttributeSet attrs, int defStyle) { 

    super(context, attrs, defStyle); 
} 

public void init(HomeFragment homeFragment){ 
    this.mHomeFragment = homeFragment; 
    paint.setStyle(Paint.Style.STROKE); 
    paint.setStrokeWidth(6); 
    paint.setColor(Color.rgb(203,156,76)); 
    setCoordinates(); 
} 

public void setCoordinates(){ 
    new Thread(new Runnable() { 
     @Override 
     public void run() { 
      while (true){ 
       switch (currentLine){ 
        case 0: 
         if(x1<width) { 
          x1 += stepLength; 
         }else { 
          currentLine = 1; 
         } 
         break; 
        case 1: 
         if(y2<=height){ 
          y2 += stepLength; 
         }else { 
          currentLine = 2; 
         } 
         break; 
        case 2: 
         if(x3>=0){ 
          x3 -= stepLength; 
         }else { 
          currentLine = 3; 
         } 
         break; 
        case 3: 
         if(y4 >= 0){ 
          y4 -= stepLength; 
         }else { 
          currentLine = 0; 
          x1 = 0; 
          y2 = 0; 
          x2 = width; 
          y2 = 0; 
          x3 = width; 
          y3 = height; 
          x4 = 0; 
          y4 = height; 
         } 
         break; 
       } 
       mHomeFragment.getActivity().runOnUiThread(new Runnable() { 
        @Override 
        public void run() { 
         invalidate(); 
        } 
       }); 
       try { 
        Thread.sleep(50); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 

     } 
    }).start(); 

} 


int max=100; 
int progress=20; 
@Override 
protected void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 
    switch (currentLine){ 
     case 0: 
      canvas.drawLine(0, 0, x1, y1, paint); 
      break; 
     case 1: 
      canvas.drawLine(0, 0, x1, y1, paint); 
      canvas.drawLine(width, 0, x2, y2, paint); 
      break; 
     case 2: 
      canvas.drawLine(0, 0, x1, y1, paint); 
      canvas.drawLine(width, 0, x2, y2, paint); 
      canvas.drawLine(width, height, x3, y3, paint); 
      break; 
     case 3: 
      canvas.drawLine(0, 0, x1, y1, paint); 
      canvas.drawLine(width, 0, x2, y2, paint); 
      canvas.drawLine(width, height, x3, y3, paint); 
      canvas.drawLine(0, height, x4, y4, paint); 
      break; 

    } 
} 
} 

Est-ce que quelqu'un sait comment dessiner un rectangle de coin arrondi avec une toile? Toute aide est très appréciée!

+0

voir https://stackoverflow.com/a/44987112/2252830 – pskink

Répondre

0

Vous devez utiliser drawRoundRect()

canvas.drawRoundRect(rect, rx, ry, paint); 
+0

Est-il possible que drawRoundRect pourrait dessiner un rectangle autour progressivement? – user1870797

+0

Je vais essayer plus tard. Il semble que c'est ce que je cherche. Mais je n'ai pas beaucoup de connaissances sur la courbe de Bézier et il est peu probable que je puisse le maîtriser dans un court instant. Pourriez-vous me donner un bon tutoriel sur la courbe de Bézier ou simplement me donner un exemple concret? – user1870797

+0

J'en ai lu un peu. Mais je suis confus de comprendre le concept de la méthode src.cubicTo. Je vais en lire plus à ce sujet plus tard. Merci! – user1870797

0

Il semble qu'il n'y a pas beaucoup d'informations sur la façon de dessiner un rectangle rond en Java sur Internet. J'ai donc modifié une démo js introduite par @pskink dans une version java. Ci-dessous le code complet:

class DrawRoundRectangle extends View { 
Paint paint; 
int strokWidth = 6; 
Path path; 
// define the rectangle 
int offsetX = 75; 
int offsetY = 100; 
int horizLineLength = 240; 
int vertLineLength = 40; 
int cornerRadius = 100; 

// calc some lengths for use in percent complete 
int cornerLength = (int) (2 * cornerRadius * Math.PI); 
int totalLength = cornerLength * 4 + horizLineLength * 2 + vertLineLength * 2; 
MainActivity ma; 

// calc at what accumulated length each part of the rect starts 
int startT = 0; 
int startTR = horizLineLength; 
int startR = startTR + cornerLength; 
int startBR = (int) (startR + vertLineLength); 
int startB = startBR + cornerLength; 
int startBL = startB + horizLineLength; 
int startL = startBL + cornerLength; 
int startTL = startL + vertLineLength; 

// percent complete 
int percent = 100; 
private int accumLength; 
private double d1; 
private double d2; 
private double d3; 
private double d4; 
private double d5; 
private double d6; 
private double d7; 
private double d8; 
int x1; 
int y1; 
int x2; 
int y2; 
int x; 
int y; 
double start; 
double end1; 
double end2; 
double end3; 
double end4; 
Canvas canvas; 

public DrawRoundRectangle(Context context, @Nullable AttributeSet attrs) { 
    super(context, attrs); 
    paint = new Paint(); 
    paint.setStrokeWidth(strokWidth); 
    paint.setColor(Color.rgb(203,156,76)); 
    path = new Path(); 
    Paint.Style style = paint.getStyle(); 
    paint.setStyle(style.STROKE); 
} 

float progress = 0; 
float stepLength = 0.5f; 

@Override 
protected void onDraw(Canvas canvas) { 
    //canvas.drawPath(segment, paint); 
     this.canvas = canvas; 

    drawPercentRect(progress); 
    progress+=stepLength; 
    if(progress >= 100){ 
     progress = 0; 
     path.reset(); 
    } 
} 

// draw the radius rectangle 
private void resetVars(){ 
    d1=0; 
    d2=0; 
    d3=0; 
    d4=0; 
    d5=0; 
    d6=0; 
    d7=0; 
    d8=0; 
    end1=0; 
    end2=0; 
    end3=0; 
    end4=0; 
} 
private void drawPercentRect(float percent) { 

    // percent expressed as a length-traveled-along-rect 
    accumLength = (int) (percent/100 * totalLength); 

    // clear the canvas 
    //ctx.clearRect(0, 0, canvas.width, canvas.height); 

    // top line 
    resetVars(); 
    d1 = accumLength - startT; 
    d1 = Math.min(d1, horizLineLength); 
    stepLength = 0.5f; 
    if (d1 > 0) { 
     x1 = offsetX + cornerRadius; 
     y1 = offsetY; 
     x2 = (int) (offsetX + cornerRadius + d1); 
     y2 = offsetY; 
     drawLine(x1, y1, x2, y2); 
    } 

    // top-right corner 
    d2 = accumLength - startTR; 
    d2 = Math.min(d2, cornerLength); 
    if (d2 > 0) { 
     x = offsetX + 50 + horizLineLength; 
     y = offsetY; 
     start = 270; 
     end1 = 90*(d2/cornerLength); 
     drawCorner(x, y, start, end1); 
    } 

    // right line 
    d3 = accumLength - startR; 
    d3 = Math.min(d3, vertLineLength); 
    if (d3 > 0) { 
     x1 = offsetX + cornerRadius + horizLineLength + cornerRadius/2; 
     y1 = offsetY + cornerRadius/2; 
     x2 = offsetX + cornerRadius + horizLineLength + cornerRadius/2; 
     y2 = (int) (offsetY + cornerRadius/2 + d3); 
     drawLine(x1, y1, x2, y2); 
    } 

    // bottom-right corner 
    d4 = accumLength - startBR; 
    d4 = Math.min(d4, cornerLength); 
    if (d4 > 0) { 
     x = offsetX + horizLineLength+cornerRadius/2; 
     y = offsetY + vertLineLength; 
     start = 0; 
     //end = (int) ((d/cornerLength) * Math.PI/2); 
     end2 = 90*(d4/cornerLength); 
     drawCorner(x, y, start, end2); 
    } 

    // bottom line 
    d5 = accumLength - startB; 
    d5 = Math.min(d5, horizLineLength); 
    if (d5 > 0) { 
     x1 = offsetX + cornerRadius + horizLineLength; 
     y1 = offsetY + cornerRadius + vertLineLength; 
     x2 = (int) (offsetX + cornerRadius + horizLineLength - d5); 
     y2 = offsetY + cornerRadius + vertLineLength; 
     drawLine(x1, y1, x2, y2); 
    } 

    // bottom-left corner 
    d6 = accumLength - startBL; 
    d6 = Math.min(d6, cornerLength); 
    if (d6 > 0) { 
     x = offsetX + cornerRadius/2; 
     y = offsetY + vertLineLength; 
     start = 90; 
     end3 = 90*(d6/cornerLength); 
     drawCorner(x, y, start, end3); 
    } 

    // left line 
    d7 = accumLength - startL; 
    d7 = Math.min(d7, vertLineLength); 
    if (d7 > 0) { 
     x1 = offsetX + cornerRadius/2; 
     y1 = offsetY + cornerRadius/2 + vertLineLength; 
     x2 = offsetX + cornerRadius/2; 
     y2 = (int) (offsetY + cornerRadius/2 + vertLineLength - d7); 
     drawLine(x1, y1, x2, y2); 
    } 

    // top-left corner 
    d8 = accumLength - startTL; 
    d8 = Math.min(d8, cornerLength); 
    if (d8 > 0) { 
     x = offsetX+cornerRadius/2; 
     y = offsetY; 
     start = 180; 
     end4 = 90*(d8/cornerLength); 
     drawCorner(x, y, start, end4); 
    } 

} 

private void drawLine(int x1, int y1, int x2, int y2) { 
    //ctx.beginPath(); 
    path.moveTo(x1, y1); 
    path.lineTo(x2, y2); 
    canvas.drawPath(path, paint); 
    //ctx.stroke(); 
} 

private void drawCorner(int x, int y, double start, double end) { 
    if(end<90){ 
     progress+=4*stepLength; 
    } 
    path.arcTo(x, y, x + cornerRadius, y + cornerRadius, (float) start(float) end,true); 
    canvas.drawPath(path, paint); 
} 

public void start(final MainActivity ma) { 
    this.ma = ma; 
    new Thread(new Runnable() { 
     @Override 
     public void run() { 
      while (true) { 
       ma.runOnUiThread(new Runnable() { 
        @Override 
        public void run() { 
         invalidate(); 
        } 
       }); 
       try { 
        Thread.sleep(50); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 

     } 
    }).start(); 

} 
} 
+0

maintenant le comparer à [this] (https://pastebin.com/raw/qtjVq2jY), et oui, il y a assez d'informations sur la façon de dessiner le rectangle rond: tout vous avez besoin de lire la documentation 'android.graphics.Canvas' ou/et' android.graphics.Path', rien de plus – pskink

+0

@pskink Cette solution est incroyablement courte et propre. Je vais essayer plus tard. – user1870797

+0

la prochaine fois essayer de lire la documentation officielle (c'est ce que je vous ai dit 3 fois déjà) – pskink