J'ai la vue personnalisée suivante:
C'est ce que j'ai réalisé en utilisant la méthode Canvas 'drawArc()
. Cependant, avec cette méthode drawArc()
, je ne peux pas limiter le rayon intérieur de l'arc.
Ce que j'aimerais avoir, c'est quelque chose comme ceci:
où il ne reste qu'un anneau extérieur.
Ce dont j'ai besoin, c'est d'une fonction drawArc()
où je peux définir le rayon intérieur de l'arc. Quelqu'un a une idée de comment faire ça?
(BTW, la peinture de la zone intérieure ne fonctionne pas, car elle doit être transparente. Peindre un cercle intérieur avec Color.TRANSPARENT
après avoir peint les cônes rouges et bleus ne supprime pas l'ancienne couleur. Il met juste un autre calque sur le dessus, qui est transparent et à travers lequel je peux toujours voir le rouge et le bleu)
Vous pouvez peindre sur la zone intérieure en utilisant le xfermode PorterDuff appelé "Clear". Cela effacera les pixels.
Tu peux le faire:
Paint paint = new Paint();
final RectF rect = new RectF();
//Example values
rect.set(mWidth/2- mRadius, mHeight/2 - mRadius, mWidth/2 + mRadius, mHeight/2 + mRadius);
Paint.setColor(Color.GREEN);
Paint.setStrokeWidth(20);
Paint.setAntiAlias(true);
Paint.setStrokeCap(Paint.Cap.ROUND);
Paint.setStyle(Paint.Style.STROKE);
canvas.drawArc(rect, -90, 360, false, Paint);
La clé est dans Paint.setStyle(Paint.Style.STROKE);
, elle recadre le centre de l'arc avec le trait que vous définissez dans setStrokeWidth (dans l'exemple dessine un arc avec un rayon de mRadius et 20px d'épaisseur).
J'espère que ça aide!
private static final float CIRCLE_LIMIT = 359.9999f;
/**
* Draws a thick arc between the defined angles, see {@link Canvas#drawArc} for more.
* This method is equivalent to
* <pre><code>
* float rMid = (rInn + rOut) / 2;
* Paint.setStyle(Style.STROKE); // there's nothing to fill
* Paint.setStrokeWidth(rOut - rInn); // thickness
* canvas.drawArc(new RectF(cx - rMid, cy - rMid, cx + rMid, cy + rMid), startAngle, sweepAngle, false, Paint);
* </code></pre>
* but supports different fill and stroke paints.
*
* @param canvas
* @param cx horizontal middle point of the oval
* @param cy vertical middle point of the oval
* @param rInn inner radius of the arc segment
* @param rOut outer radius of the arc segment
* @param startAngle see {@link Canvas#drawArc}
* @param sweepAngle see {@link Canvas#drawArc}, capped at ±360
* @param fill filling Paint, can be <code>null</code>
* @param stroke stroke Paint, can be <code>null</code>
* @see Canvas#drawArc
*/
public static void drawArcSegment(Canvas canvas, float cx, float cy, float rInn, float rOut, float startAngle,
float sweepAngle, Paint fill, Paint stroke) {
if (sweepAngle > CIRCLE_LIMIT) {
sweepAngle = CIRCLE_LIMIT;
}
if (sweepAngle < -CIRCLE_LIMIT) {
sweepAngle = -CIRCLE_LIMIT;
}
RectF outerRect = new RectF(cx - rOut, cy - rOut, cx + rOut, cy + rOut);
RectF innerRect = new RectF(cx - rInn, cy - rInn, cx + rInn, cy + rInn);
Path segmentPath = new Path();
double start = toRadians(startAngle);
segmentPath.moveTo((float)(cx + rInn * cos(start)), (float)(cy + rInn * sin(start)));
segmentPath.lineTo((float)(cx + rOut * cos(start)), (float)(cy + rOut * sin(start)));
segmentPath.arcTo(outerRect, startAngle, sweepAngle);
double end = toRadians(startAngle + sweepAngle);
segmentPath.lineTo((float)(cx + rInn * cos(end)), (float)(cy + rInn * sin(end)));
segmentPath.arcTo(innerRect, startAngle + sweepAngle, -sweepAngle);
if (fill != null) {
canvas.drawPath(segmentPath, fill);
}
if (stroke != null) {
canvas.drawPath(segmentPath, stroke);
}
}
Peut être étendu à l'arc ovale en dupliquant rInn
et rOut
pour les directions x et y.
Ne faisait pas non plus partie de la question, mais pour dessiner un texte au milieu d'un segment:
textPaint.setTextAlign(Align.CENTER);
Path midway = new Path();
float r = (rIn + rOut) / 2;
RectF segment = new RectF(cx - r, cy - r, cx + r, cy + r);
midway.addArc(segment, startAngle, sweepAngle);
canvas.drawTextOnPath("label", midway, 0, 0, textPaint);
dessin Cercle et Arc. le code suivant est peu sale mais cela peut aider
int sweepAngle sweepAngle = (360/7)%360;
int startAngle = -90;
int x = getWidth()/2;
int y = getHeight()/2;
int radius;
radius = getWidth()/2-50;
Paint.setStyle(Paint.Style.STROKE);
Paint.setStrokeWidth(50);
Paint.setColor(Color.WHITE);
Paint.setColor(Color.parseColor("#CD5C5C"));
mBarPaintFill.setAntiAlias(true);
canvas.drawCircle(x , y , radius, Paint);
Paint.setColor(Color.BLUE);
for (int i = 1 ; i<=5 ; i++){
canvas.drawArc(x-radius,y-radius,x+radius,y+radius,startAngle,sweepAngle,false,Paint);
startAngle = (startAngle + sweepAngle+20)%360;
}
Vous pouvez essayer de suivre ShapeDrawable
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android" >
<item>
<shape Android:shape="oval" >
<size
Android:height="56dp"
Android:width="56dp" />
<stroke
Android:width="10dp"
Android:color="#0000ff" />
</shape>
</item>
<item>
<shape Android:shape="oval" >
<size
Android:height="24dp"
Android:width="25dp" />
<stroke
Android:dashGap="10dp"
Android:dashWidth="10dp"
Android:width="10dp"
Android:color="#FF0000" />
</shape>
</item>