42

I have seen a lot of examples of creating custom views and layouts in android. What I've learned from them is that the measure (as said on Android developer's site) method is onMeasure(), which has widthMeasureSpec and heightMeasureSpec as parameters.

  1. What is the actual meaning of those parameters?
  2. What are their initial values?
  3. With what values they are called if the custom view that I am creating is the parent view for my activity?

I am really very confused about these questions.

Cat
  • 66,919
  • 24
  • 133
  • 141
theimpatientcoder
  • 1,184
  • 3
  • 19
  • 32
  • 1
    Have you read [further into the docs](http://developer.android.com/reference/android/view/View.MeasureSpec.html)? – Cat Jan 24 '13 at 04:02
  • 1
    i will have a further look at it. thankyou Eric – theimpatientcoder Jan 24 '13 at 04:32
  • hello Eric, Can you please help me figure out following thing? I have written a custom layout and i want to use it as my root layout for an activity. I have also included child views in it (while writing the XML file). Can you please help me figure out the series of events that take place since setContentView in the activity gets called. when(and whose/which) does measure and onMeasure gets called? how does onMeasure calculate space for its children? i did read the docs, and was able to understand it fairly, but still these questions remain in my mind. Sorry for my English. – theimpatientcoder Jan 25 '13 at 03:00
  • That's also in [the documentation](http://developer.android.com/guide/topics/ui/how-android-draws.html) (paragraphs 3 and onward are all about `measure()` and how the measurement works). – Cat Jan 25 '13 at 03:10
  • can you PLEASE elaborate it for me in simple words? please? can you please help me to think "how to develop logic for onMeasure()" for custom layouts? – theimpatientcoder Jan 25 '13 at 03:54
  • You shouldn't be developing your own logic for measuring the layouts. What you return from that method is what's important, which is what's outlined in [threads like this one](http://stackoverflow.com/a/8403680/1438733). Then, let Android take your measurement specs and handle them. Please, do some research... :) – Cat Jan 25 '13 at 03:58
  • thank you Eric. I am trying :) – theimpatientcoder Jan 25 '13 at 04:34
  • hello Eric, i have read into docs and now i have fair idea of why onMeasure and onLayout is used. but still i am facing problems. i you could please go through http://stackoverflow.com/questions/14516070/understanding-onmeasure-in-android-custom-layout and explain me ( in your free time, ofcourse) it will be of great great help. If i could understand this, i think i will have a fair insight about all these things. Please help. and sorry to bother you again. You have been of great assistance . – theimpatientcoder Jan 25 '13 at 05:47

2 Answers2

77

widthMeasureSpec and heightMeasureSpec are compound variables. Meaning while they are just plain old ints, they actually contain two separate pieces of data.

The first part of data stored in these variables is the available space (in pixels) for the given dimension.

You can extract this data using this convenience method:

int widthPixels = View.MeasureSpec.getSize( widthMeasureSpec );

The second piece of data is the measure mode, it is stored in the higher order bits of the int, and is one of these possible values:

View.MeasureSpec.UNSPECIFIED
View.MeasureSpec.AT_MOST
View.MeasureSpec.EXACTLY

You can extract the value with this convenience method:

int widthMode = View.MeasureSpec.getMode( widthMeasureSpec );

You can do some logic, change one or both of these, and then create a new meassureSpec using the last convenience method:

int newWidthSpec = View.MeasureSpec.makeMeasureSpec( widthPixels, widthMode  );

And pass that on down to your children, usually by calling super.onMeasure( widthMeasureSpec, heightMeasureSpec );

In onMeasure() the MeasureSpec pattern serves the purpose of passing in the maximum allowed space your view and it's children are allowed to occupy. It also uses the spec mode as a way of placing some additional constrains on the child views, informing them on how they are allowed to use the available space.

A good example of how this is used is Padding. ViewGroups take the available width and height, and subtract out their padding, and then create a new meassureSpec, thus passing a slightly smaller area to their children.

Adam
  • 25,966
  • 23
  • 76
  • 87
  • 1
    Shouldn't it be: int widthPixels = View.MeasureSpec.getSize( widthMeasureSpec ); and int widthMode = View.MeasureSpec.getMode( widthMeasureSpec ); – André Restivo Feb 19 '14 at 10:54
  • How parent can set Mode for childs? for example if I have view with wrapcontent and then add child to it, in child View.MeasureSpec.getMode is what should be? – Mahdi Dec 09 '18 at 15:23
2

This article will be helpful for you. I'm answering your question from the context of the article.

1. What is the actual meaning of those parameters?

Answer:

widthMeasureSpec Horizontal space requirements as imposed by the parent view to the child view.

heightMeasureSpec Vertical space requirements as imposed by the parent view to the child view

2. What are their initial values?

Answer:

when MODE_SHIFT = 30 when values are -

MeasureSpec.UNSPECIFIED = 0 << MODE_SHIFT = 0

MeasureSpec.EXACTLY = 1 << MODE_SHIFT = 1073741824

MeasureSpec.AT_MOST = 2 << MODE_SHIFT = 2147483648

3. With what values they are called if the custom view that I am creating is the parent view for my activity?

Answer: It will depend on what height and width you give in the parent view. You will get a good insight about it in the last part of the article which also shows a chart below I mentioned -

enter image description here

Gk Mohammad Emon
  • 6,084
  • 3
  • 42
  • 42