measuring a view before rendering it
Asked Answered
D

5

59

I need to find out how big a view will be after attaching it to its parent.

I have overridden this method:

onMeasure(int, int);

but it looks like this method is invoked only when I actually add my custom view to it's container using:

addView(myView);

Do you think there is a way to get this information before rendering the view itself? Basically I need to know the actuall size before attaching it and not attach the view at all if it would take more certain amount of space.

anybody?

Decalescence answered 13/5, 2010 at 13:22 Comment(1)
Check this solution: https://mcmap.net/q/88183/-determining-the-size-of-an-android-view-at-runtimeHamish
A
89

If you want to get the width and height before your activity has added it to its view hierarchy, measured and layed it out you will have to call measure() on the View yourself before calling getMeasuredWidth() or getMeasuredHeight().

As the measured width and height are set after measure has been called (which in turn calls onMeasure()) they will return 0 before this point. You will have to supply MeasureSpecs to measure(..) that will vary depending on your needs.

The MeasureSpecs that allow the children to impose any constraints themselves look like

int widthMeasureSpec = MeasureSpec.makeMeasureSpec(*some width*, MeasureSpec.EXACTLY);
int heightMeasureSpec = MeasureSpec.makeMeasureSpec(*some height*, MeasureSpec.EXACTLY);

Important point. (has been changed in new API) The width passed in above can either be explicit px or ViewGroup.LayoutParams.WRAP_CONTENT or ViewGroup.LayoutParams.FILL_PARENT.

Its also worth noting when your view is measured in the actual destination hierarchy the MeasureSpec that will be passed to measure() will be configured based upon the containing ViewGroups layout logic. It may be called more than once if the first measure vals are not valid when considered in the context of this parent viewGroup / its own layout constraits / the constraints of any sibling child-views. Without waiting for the viewGroup to call measure() before implementing any logic dependent on the measured size it would be hard (depending on the situation) to get the final measuredWidth & height from the above solution, but in all the instances i have used the above technique it has fit the purpose, but they have been relatively simple. If you really do need to measure in context you should probably just do it after onLayout() has returned and explicitly set any changes then requestLayout() again.

Alloplasm answered 6/12, 2011 at 16:53 Comment(5)
Your Important Point is wrong, you can't pass WRAP_CONTENT or FILL_PARENT as the first param of makeMeasureSpec(int, int). The value must be greater than 0 or less than 1073741823.Presser
Seems like this methods impl changed at 17. I answered this nearly 5 years ago :)Alloplasm
@Alloplasm the docs for MeasureSpec.makeMeasureSpec() have been updated as well to reflect the new restrictions. Would you mind putting a strike-through or something in that "important point" section?Subtangent
Seems like this change has also removed the "The value must be greater than 0 or less than 1073741823" info though.Alloplasm
some width and some height are not very useful. The official docs aren't either.Leannaleanne
A
7

OnMeasure does not tell you the size of the View. Instead, it asks your custom View to set its size by providing some constraints enforced by the parent View.

This is from the SDK documentation:

The first pair is known as measured width and measured height. These dimensions define how big a view wants to be within its parent (see Layout for more details.) The measured dimensions can be obtained by calling getMeasuredWidth() and getMeasuredHeight().

The second pair is simply known as width and height, or sometimes drawing width and drawing height. These dimensions define the actual size of the view on screen, at drawing time and after layout. These values may, but do not have to, be different from the measured width and height. The width and height can be obtained by calling getWidth() and getHeight().

After layout you can call getWidth() and getHeight() to find the final size of your custom View.

Auvil answered 13/5, 2010 at 14:0 Comment(0)
B
7

first call

 view.measure(0, 0);

then get

view.getMeasuredWidth() or view.getMeasuredHeight()

Basque answered 12/12, 2018 at 8:38 Comment(0)
I
0

You should be able to use getMesauredWith() and getMeasuredHeight()

http://developer.android.com/reference/android/view/View.html#getMeasuredWidth%28%29

Ilka answered 13/5, 2010 at 13:46 Comment(1)
you have to call measure() yourself first - see my answerAlloplasm
M
0

I'm having the same problem. I guess the only way is to render it first, then remove it after if it meets the size condition. Seems a bit of an odd way, but Android only seems to know the dimensions after drawing.

Maternal answered 18/8, 2011 at 12:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.