2011-07-11 23 views
23

Necesito poder acceder al tamaño del lienzo de la vista para realizar algunos cálculos. Por alguna razón, el tamaño de la vista pasó a onSizeChanged es diferente del tamaño del lienzo pasado a onDraw. Mi solución actual utiliza una bandera booleana para determinar cuándo debo hacer los cálculos.¿Cómo puedo obtener el tamaño del lienzo de una vista personalizada fuera del método onDraw?

La solución ideal sería me permite hacer estos cálculos en el método onSizeChanged, por lo que me pregunto ... ¿hay alguna manera de que pueda ponerme en contacto con el objeto Canvas (o al menos sus dimensiones) fuera de la onDraw ¿método?

Mi código está por debajo. Dibuja el radio de un círculo en un ángulo dado. Cuando uso canvas.centerX() para determinar los puntos de inicio y los puntos finales para el radio, todo funciona perfectamente. Si utilizo los parámetros pasados ​​a onSizeChanged, ni siquiera está remotamente cerca de corregir.

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

Respuesta

31

Para fines de dibujo, no debería utilizar realmente las dimensiones del objeto Canvas.

Simplemente utilice las dimensiones que se le proporcionaron en el método onSizeChanged. Puede almacenar las dimensiones para usar en el método onDraw o redimensionar/dibujar a un mapa de bits de respaldo que puede dibujar más tarde.

Actualización:

batida rápidamente hasta un cierto código, parece que esto funciona:

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

Actualización 2

Tras la actualización del código círculo.

Podemos hacer esto:

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

Verás que esto ahora funciona en cualquier punto de vista del tamaño.

+0

Estaría bien con eso, pero el método onSizeChanged no me da los números correctos. Por ejemplo, supongamos que quisiera dibujar texto en el centro de la vista. Si guardo los valores pasados ​​a onSizeChanged, y los uso para determinar dónde debe dibujarse el texto, no se dibujan en el lugar correcto. Si utilizo las dimensiones del lienzo para determinar dónde debe dibujarse el texto, funciona perfectamente. – dfetter88

+1

Si compara sus valores w/2 y h/2 con los resultados de los métodos canvas.centerX() y canvas.centerY(), verá que los valores son diferentes. – dfetter88

+0

Cuando uso su código, el texto no aparece en absoluto porque w/2 y h/2 dan coordenadas que son más grandes que el lienzo. Por lo tanto, el texto se dibuja en un lugar que no se muestra en la pantalla. – dfetter88

Cuestiones relacionadas