web-dev-qa-db-fra.com

Comment obtenir la taille du canevas d'une vue personnalisée en dehors de la méthode onDraw?

Je dois pouvoir accéder à la taille du canevas de la vue pour effectuer certains calculs. Pour une raison quelconque, la taille de la vue passée à onSizeChanged est différente de la taille du canevas passée à onDraw. Ma solution de contournement actuelle utilise un indicateur booléen pour déterminer quand j'ai besoin de faire les calculs.

La solution idéale me permettrait de faire ces calculs dans la méthode onSizeChanged, donc je me demande ... est-il possible de récupérer l'objet Canvas (ou du moins c'est dimensions) en dehors de la méthode onDraw?

Mon code est ci-dessous. Il dessine le rayon d'un cercle à un angle donné. Lorsque j'utilise canvas.centerX() pour déterminer les points de départ et d'arrivée du rayon, tout fonctionne parfaitement. Si j'utilise les paramètres passés dans onSizeChanged, ce n'est même pas à distance pour corriger.

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
  super.onSizeChanged(w, h, oldw, oldh);
  mSizeChanged = true;
}

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

  if (mSizeChanged) {
    RectF bounds = new RectF(canvas.getClipBounds());
    float centerX = bounds.centerX();
    float centerY = bounds.centerY();
    float radianAngle = (float) Math.toRadians(mStartAngle);

    mRadius[0] = center;
    mRadius[1] = center;
    mRadius[2] = center + center * FloatMath.cos(radianAngle);
    mRadius[3] = center + center * FloatMath.sin(radianAngle);
    mSizeChanged = false;
  }

  mPaint.setColor(0xFF330000);
  mPaint.setStrokeWidth(1);
  canvas.drawLines(mRadius, mPaint);
}
30
dfetter88

À des fins de dessin, vous ne devez pas vraiment utiliser les dimensions de l'objet Canvas.

Utilisez simplement les dimensions qui vous sont fournies dans la méthode onSizeChanged. Vous pouvez soit stocker les dimensions à utiliser dans la méthode onDraw, soit redimensionner/dessiner sur un bitmap de support avec lequel vous pourrez dessiner plus tard.

Mise à jour:

A rapidement fouetté du code, il semble que cela fonctionne:

public class CustomView extends View{
    private Paint paint;
    private int w;
    private int h;

    public CustomView(Context context, AttributeSet attr) {
        super(context, attr);
        Paint = new Paint();
        Paint.setTextAlign(Align.CENTER);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        this.w = w;
        this.h = h;
        super.onSizeChanged(w, h, oldw, oldh);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawColor(Color.WHITE);
        canvas.drawText("TEST", w/2, h/2, Paint);   
    }
}

mise à jour 2

Après la mise à jour du code du cercle.

Nous pouvons le faire:

   @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawColor(Color.WHITE);
        float centerX = (float) w/2;
        float centerY = (float) h/2;
        float radianAngle = (float) Math.toRadians(startAngle);

        radius[0] = centerX;
        radius[1] = centerY;
        radius[2] = centerX + centerX * FloatMath.cos(radianAngle);
        radius[3] = centerY + centerY * FloatMath.sin(radianAngle);

        Paint.setColor(0xFF330000);
        Paint.setStrokeWidth(1);
        canvas.drawLines(radius, Paint);
    }

Vous verrez que cela fonctionne maintenant sur n'importe quelle vue de taille.

32
Che Jami