Как я могу получить размер холста пользовательского представления вне метода onDraw? - PullRequest
27 голосов
/ 11 июля 2011

Мне нужно иметь доступ к размеру холста представления для выполнения некоторых вычислений.По какой-то причине размер представления, переданного в onSizeChanged, отличается от размера холста, переданного в onDraw.Мой текущий обходной путь использует логический флаг, чтобы определить, когда мне нужно выполнить вычисления.

Идеальное решение позволило бы мне выполнить эти вычисления в методе onSizeChanged, поэтому мне интересно ... естьВ любом случае я могу получить объект Canvas (или, по крайней мере, его размеры) вне метода onDraw?

Мой код приведен ниже.Это рисует радиус круга под заданным углом.Когда я использую canvas.centerX(), чтобы определить начальные и конечные точки для радиуса, все работает отлично.Если я использую параметры, переданные в onSizeChanged, он даже близко не подходит к правильному.

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

1 Ответ

32 голосов
/ 11 июля 2011

В целях рисования вам не следует использовать размеры объекта Canvas.

Просто используйте размеры, предоставленные вам в методе onSizeChanged.Вы можете сохранить размеры для использования в методе onDraw или изменить размер / отрисовку на растровое изображение, которое вы сможете рисовать позже.

Обновление:

Быстровзяли какой-то код, похоже, это работает:

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

Обновление 2

После обновления кода круга.

Мы можем сделать это:

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

Вы увидите, что теперь это работает при любом размере.

...