6

I noticed that my application's view returns 0 for getWidth() and getHeight() after onMeasure() has already been called. This only happens on a handful of devices, for most android devices the following code works fine. My checkViewAndLoad() function loads a scaled bitmap depending on the size of the view.

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    Log.d("widthMeasureSpec", Integer.toString(MeasureSpec.getSize(widthMeasureSpec)));
    Log.d("heightMeasureSpec", Integer.toString(MeasureSpec.getSize(heightMeasureSpec)));
    Log.d("viewWidth", Integer.toString(getWidth()));
    Log.d("viewHeight", Integer.toString(getHeight()));

    checkViewAndLoad();
}

Here is a log of a device (Motorola Droid Razr Maxx) that returns zero for getWidth()/getHeight() after onMeasure():

09-03 20:55:58.359: D/widthMeasureSpec(29496): 540
09-03 20:55:58.359: D/heightMeasureSpec(29496): 720
09-03 20:55:58.359: D/viewWidth(29496): 0
09-03 20:55:58.359: D/viewHeight(29496): 0

I also tried to setMeasuredDimensions() manually, but that hand no affect on the logs.

Can someone tell me what I'm doing wrong here, or how to get the width/height of a SurfaceView after onMeasure() has been called?

dsmflyer
  • 81
  • 1
  • 6

2 Answers2

10

Use getMeasuredWidth/Height() here. getWidth/Height() aren't valid until after a layout.

alex
  • 6,359
  • 1
  • 23
  • 21
  • What do you mean by /Height() – Steve Moretz Feb 06 '19 at 19:51
  • getMeasuredWidth() / getMeasuredHeight() and getWidth() / getHeight(). – alex Feb 07 '19 at 03:14
  • I get what you mean but it looks like divide and also " aren't valid until after a layout." doesn't make sense,I'll edit it if you want. – Steve Moretz Feb 07 '19 at 07:49
  • Steve, your edit doesn't distinguish between a draw and a layout, they are different steps. The measured getters are valid after measure(), specifically setMeasuredDimensions(), is called and the plain getters are valid after layout(). Drawing happens a whole lot more often than either of these which typically only get called after some kind of size change or a requestLayout() call. – alex Feb 08 '19 at 04:43
  • There's a lot more about the view framework's callbacks here: https://developer.android.com/reference/android/view/View#implementing-a-custom-view – alex Feb 08 '19 at 04:45
  • Yes thanks for the info but the edit provides what OP is looking for to have the valid getWidth value which happens after the view is drawn and,Your suggestion getMeasuredWidth which gives a valid value on Measure.Maybe it's not the best way but OP has asked for it.But my provided method is better to be used outside of a customview but also works inside it.Inside the customview it's better to override the methods to get a valid value... – Steve Moretz Feb 08 '19 at 07:11
1

Try This way

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec));

    Log.d("widthMeasureSpec", Integer.toString(MeasureSpec.getSize(widthMeasureSpec)));
    Log.d("heightMeasureSpec", Integer.toString(MeasureSpec.getSize(heightMeasureSpec)));
    Log.d("viewWidth", Integer.toString(getWidth()));
    Log.d("viewHeight", Integer.toString(getHeight()));

    if(getMeasuredWidth()!=0 && getMeasuredHeight()!=0){
              checkViewAndLoad();
    }

}
Biraj Zalavadia
  • 28,348
  • 10
  • 61
  • 77