2016-08-29 1 views
3

J'essaie de tracer un arc de cercle pour représenter la température, mais j'ai de la difficulté à y parvenir. Au cours de ma recherche, j'ai trouvé ces solutionsAndroid: Dessiner un arc à l'intérieur d'un cercle

This one I couldn't understand what is the scale method for, and is drawing more than one arch, which confused me a bit

This post gave it a fixed size where I need the size to be controlled by the custom view in my XML layout

From here I understood the concept the degrees but I didn't understand how to determine the oval size

Ce que j'ATTEINT jusqu'à présent

@Override 
protected void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 

    int startTop = 0; 
    int startLeft = 0; 
    int endBottom = getHeight()/2; 
    int endRight = endBottom;// This makes an equal square. 

    int centerX = getWidth()/2; 
    int centerY = getHeight()/2; 

    int upperEdgeX = (int) (centerX + getWidth()/2 * Math.cos(270 * Math.PI/180)); 
    int upperEdgeY = (int) (centerY + getWidth()/2 * Math.sin(270 * Math.PI/180)); 

    int bottomEdgeX = (int) (centerX + getWidth()/2 * Math.cos(90 * Math.PI/180)); 
    int bottomEdgeY = (int) (centerY + getWidth()/2 * Math.sin(90 * Math.PI/180)); 

    int leftEdgeX = (int) (centerX + getWidth()/2 * Math.cos(180 * Math.PI/180)); 
    int leftEdgeY = (int) (centerY + getWidth()/2 * Math.sin(180 * Math.PI/180)); 

    int rightEdgeX = (int) (centerX + getWidth()/2 * Math.cos(0 * Math.PI/180)); 
    int rightEdgeY = (int) (centerY + getWidth()/2 * Math.sin(0 * Math.PI/180)); 

    RectF rect = new RectF(startTop, startLeft, endRight, endBottom); 
    canvas.drawCircle(centerX, centerY, getWidth()/2, mBasePaint); 


    canvas.drawCircle(centerX, centerY, getWidth()/3, mCenterPaint); // White circle 
} 

MISE À JOUR: J'ai besoin moi d'être comme un graphique à tarte Donut w ici le milieu tiendra le degré

MISE À JOUR 2:

Je suis en train d'avoir quelque chose comme ça

enter image description here

+0

pourrait vous envoyer une image de ce que vous essayons d'atteindre? Je ne sais pas à quoi ressemble un "diagramme de camemberts";) – 0X0nosugar

+0

@ 0X0nosugar Mis à jour :) –

+0

Cet article pourrait vous aider. [Check out] (http://stackoverflow.com/questions/3874424/android-looking-for-a-drawarc-method-with-inner-outer-radius) –

Répondre

5

La coutume View suivant dessine deux arcs de connexion pour former un cercle ainsi que d'un cercle intérieur.

enter image description here

De plus, je laisse remplir le rectangle utilisé pour dessiner l'arc et utiliser un fond jaune pour le View, l'arrière-plan d'activité est sombre. (Ces fonctionnalités supplémentaires sont destinés à obtenir une meilleure impression de la façon dont dessiner un cercle/fonctionne un arc, ils peuvent aider avec le débogage.)

La vue personnalisée:

public class MySimpleView extends View{ 

private static final int STROKE_WIDTH = 20; 
private Paint mBasePaint, mDegreesPaint, mCenterPaint, mRectPaint; 
private RectF mRect; 
private int centerX, centerY, radius; 

public MySimpleView(Context context) { 
    super(context); 
    init(); 
} 

public MySimpleView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    init(); 
} 

public MySimpleView(Context context, AttributeSet attrs, int defStyleAttr) { 
    super(context, attrs, defStyleAttr); 
    init(); 
} 

private void init() 
{ 
    mRectPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 
    mRectPaint.setColor(ContextCompat.getColor(getContext(), R.color.magenta)); 
    mRectPaint.setStyle(Paint.Style.FILL); 

    mCenterPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 
    mCenterPaint.setColor(ContextCompat.getColor(getContext(), R.color.white)); 
    mCenterPaint.setStyle(Paint.Style.FILL); 

    mBasePaint = new Paint(Paint.ANTI_ALIAS_FLAG); 
    mBasePaint.setStyle(Paint.Style.STROKE); 
    mBasePaint.setStrokeWidth(STROKE_WIDTH); 
    mBasePaint.setColor(ContextCompat.getColor(getContext(), R.color.blue)); 

    mDegreesPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 
    mDegreesPaint.setStyle(Paint.Style.STROKE); 
    mDegreesPaint.setStrokeWidth(STROKE_WIDTH); 
    mDegreesPaint.setColor(ContextCompat.getColor(getContext(), R.color.green)); 

} 


@Override 
protected void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 

    // getHeight() is not reliable, use getMeasuredHeight() on first run: 
    // Note: mRect will also be null after a configuration change, 
    // so in this case the new measured height and width values will be used: 
    if (mRect == null) 
    { 
     // take the minimum of width and height here to be on he safe side: 
     centerX = getMeasuredWidth()/ 2; 
     centerY = getMeasuredHeight()/ 2; 
     radius = Math.min(centerX,centerY); 

     // mRect will define the drawing space for drawArc() 
     // We have to take into account the STROKE_WIDTH with drawArc() as well as drawCircle(): 
     // circles as well as arcs are drawn 50% outside of the bounds defined by the radius (radius for arcs is calculated from the rectangle mRect). 
     // So if mRect is too large, the lines will not fit into the View 
     int startTop = STROKE_WIDTH/2; 
     int startLeft = startTop; 

     int endBottom = 2 * radius - startTop; 
     int endRight = endBottom; 

     mRect = new RectF(startTop, startLeft, endRight, endBottom); 
    } 

    // just to show the rectangle bounds: 
    canvas.drawRect(mRect, mRectPaint); 

    // subtract half the stroke width from radius so the blue circle fits inside the View 
    canvas.drawCircle(centerX, centerY, radius - STROKE_WIDTH/2, mBasePaint); 
    // Or draw arc from degree 192 to degree 90 like this (258 = (360 - 192) + 90: 
    // canvas.drawArc(mRect, 192, 258, false, mBasePaint); 

    // draw an arc from 90 degrees to 192 degrees (102 = 192 - 90) 
    // Note that these degrees are not like mathematical degrees: 
    // they are mirrored along the y-axis and so incremented clockwise (zero degrees is always on the right hand side of the x-axis) 
    canvas.drawArc(mRect, 90, 102, false, mDegreesPaint); 

    // subtract stroke width from radius so the white circle does not cover the blue circle/ arc 
    canvas.drawCircle(centerX, centerY, radius - STROKE_WIDTH, mCenterPaint); 
} 
} 
+0

Merci pour votre réponse bien détaillée, mais encore une question Dois-je spécifier une hauteur et une largeur statiques pour ma vue personnalisée dans les mises en page xml? Puisque l'arc est dessiné en haut de la mise en page quand je spécifie wrap_content comme largeur –

+1

@MotassemJa - En ce moment, la vue dessine dans le coin supérieur gauche (en supposant une locale LTR). Pour l'image ci-dessus j'ai utilisé 120dp pour la largeur et la hauteur. Pour que "wrap_content" fonctionne, je suppose qu'il devrait y avoir du contenu en premier. Votre vue personnalisée a-t-elle une sorte de vue enfant? – 0X0nosugar

+0

Aucune vue personnalisée est vide. Cela fonctionnerait-il si je mettais un seul élément View à l'intérieur? –