2011-07-11 21 views
23

Bazı hesaplamalar yapmak için görünüm tuvalinin boyutuna erişebilmem gerekir. Bazı nedenlerden dolayı, onSizeChanged görünümüne geçirilen görünümün boyutu, tuvalin onDraw10'a geçirilen boyutundan farklıdır. Mevcut geçici çözümüm, hesaplamaları ne zaman yapmam gerektiğini belirlemek için bir boole bayrağı kullanıyor. Ben onDraw dışında Canvas nesnenin ulaşmamın (veya en azından kendi boyutlarını) herhangi bir yolu yoktur ...Özel bir görünümün tuval boyutunu onDraw yönteminin dışında nasıl edinebilirim?

ideal çözüm beni onSizeChanged yönteminde bu hesaplamaları yapmak için izin verecek, bu yüzden merak ediyorum yöntem?

Kodum aşağıda. Belirli bir açıda dairenin yarıçapını çizer. Yarıçap için başlangıç ​​noktalarını ve bitiş noktalarını belirlemek için canvas.centerX() kullandığımda, her şey mükemmel çalışır. onSizeChanged'a iletilen parametreleri kullanırsam, düzeltmek için uzaktan bile yakın değildir.

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

cevap

31

çizim amaçları için, gerçekten Canvas nesnenin boyutlarını kullanmamalısınız.

Size sağlanan boyutları yalnızca onSizeChanged yönteminde kullanın. Boyutları onDraw10 yönteminde depolayabilir veya daha sonra çekebileceğiniz bir arka plan bitmapine yeniden boyutlandırma/çizme yapabilirsiniz.

Güncelleme: bu işler böyle

Hızla bazı kodlar kadar çırpılmış, görünüşe: daire kod güncellemenin ardından

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

Güncelleme 2

.

Bunu yapabiliriz:

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

Bu artık herhangi büyüklükteki görünümünde çalıştığını göreceksiniz.

+0

Bunun ile iyi olur, ancak onSizeChanged yöntemi bana uygun numaralar vermez. Örneğin, görünümün ortasında bir metin çizmek istediğimi varsayalım. OnSizeChanged'e iletilen değerleri saklarsam ve metnin nereye çizileceğini belirlemek için bunları kullanırsam, doğru yerde çizilmez. Metnin nereye çizileceğini belirlemek için tuval boyutlarını kullanırsam, mükemmel çalışır. – dfetter88

+1

w/2 & h/2 değerlerinizi canvas.centerX() ve canvas.centerY() yöntemleriyle karşılaştırırsanız, değerlerin farklı olduğunu görürsünüz. – dfetter88

+0

Kodunuzu kullandığımda, metin hiç görüntülenmiyor çünkü w/2 ve h/2, tuvalden daha büyük koordinatları veriyor. Böylece, metin ekranda görüntülenmeyen bir yere çizilir. – dfetter88

İlgili konular