37

I am a bit confused about MeasureSpec.UNSPECIFIED and MeasureSpec.AT_MOST. I know that when match_parent or an constant dimension value is set to layout_width or layout_height, MeasureSpec.EXACTLY will be applied when measuring the view.

Then, how about MeasureSpec.UNSPECIFIED and MeasureSpec.AT_MOST?

My understanding is that, when layout_width or layout_height is set to wrap_content, MeasureSpec.UNSPECIFIED will be applied, because wrap_content means the height or width of a view can be any size depending on the content. But many articles said that wrap_content means MeasureSpec.AT_MOST. So I am confused. I don't know when MeasureSpec.AT_MOST should be applied.

DIF
  • 2,470
  • 6
  • 35
  • 49
Kai
  • 3,775
  • 10
  • 39
  • 54

3 Answers3

73

The basic definition of how a View is sized goes like this:

MeasureSpec.EXACTLY - A view should be exactly this many pixels regardless of how big it actually wants to be.

MeasureSpec.AT_MOST - A view can be this size or smaller if it measures out to be smaller.

MeasureSpec.UNSPECIFIED - A view can be whatever size it needs to be in order to show the content it needs to show.

MeasureSpec.AT_MOST will be applied to views that have been set to WRAP_CONTENT if the parent view is bound in size. For example, your parent View might be bound to the screen size. It's children will be also bound to this size, but it might not be that big. Thus, the parent view will set the MeasureSpec to be AT_MOST which tells the child that it can be anywhere between 0 and screen size. The child will have to make adjustments to ensure that it fits within the bounds that was provided.

In special cases, the bounds do not matter. For example, a ScrollView. In the case of a ScrollView, the height of the child Views are irrelevant. As such, it will supply an UNSPECIFIED to the children Views which tells the children that they can be as tall as they need to be. The ScrollView will handle the drawing and placement for them.

DeeV
  • 35,865
  • 9
  • 108
  • 95
  • Thanks for the explanation...I am using a RecyclerView, and my items (wrapping dynamic child views) have a `wrap_content` as their height. The list repeats some of the items as it does not know how to fill in its view since the height is not fixed. I know I might need to override `onMeasure()` but I don't know how to implement it in my case. Any ideas? – Atieh Aug 12 '15 at 00:25
  • @Atieh, you mean you're trying to fill the remaining RecyclerView space with an item? – DeeV Aug 12 '15 at 00:34
  • not really, my recycleview is repeating some items in the list. My logs show N items from the network call, but the items in the list M > N. I have debugged the default implementation for `onMeasure()` and it stops at `AT_MOST`for the height every time. SO as you explained, the parent view (recycler view) is bound to the screen (match_parent for width and height) and my items have `wrap_content` for height. – Atieh Aug 12 '15 at 00:52
  • @Atieh: If recyclerView is producing more items than there exists, then the issue is in the RecyclerView.Adapter you've applied to it. RecyclerView is going to get as many items as it can until it's size is filled or until it's count as reached Adapter#getItemCount(). Measurement is dictated by the LayoutManager. – DeeV Aug 12 '15 at 03:03
  • [This is my adapter](https://github.com/Redgram/redgram-for-reddit/blob/master/Redgram/app/src/main/java/com/matie/redgram/ui/home/views/adapters/PostAdapterBase.java#L60). I have like 6 types of a specific child view that I inflate based on its type in a subclass. I get this view using an abstract method that I later implement. Thanks for the tip, maybe by looking into my adapter you can guide me better..? – Atieh Aug 13 '15 at 15:33
  • That actually looks right, so not sure why a RecyclerView would do that. – DeeV Aug 13 '15 at 16:53
2

To get a full insight please see the article first. The summery is -

  1. When the width or height of the view is a specific number, such as 100px or 100dp, the spec mode of the view is EXACTLY regardless of the measurement mode of the parent container, and the size of the view is the specific number.

  2. When the width or height of view adopts MATCH_PARENT, the spec mode of view is consistent with the measurement mode of parent container. But the value of specSize is different. When the SpecSize of the parent container is UNSPECIFIED, the specSize of the view is 0. When the SpecSize of the parent container is EXACTLY or AT_MOST, the size of the specSize of the view is the remaining space of the parent container.

  3. When the width or height of view is WRAP_CONTENT, if the SpecMode of parent container is EXACTLY or AT_MOST, the measurement mode of view is AT_MOST. When the specMode of parent container is UNSPECIFIED, the measurement mode of view is UNSPECIFIED. The measurement size of view is also affected by the measurement mode of parent container, specifically when the specMode of parent container is UNSPECIFIED. When SpecMode is EXACTLY or AT_MOST, the maximum size of specSize of view cannot exceed the remaining space of the parent container. When the specMode of the parent container is UNSPECIFIED, the size of view is 0. According to the logic of getChildMeasureSpec method, we can summarize the measurement mode of view and parent container, and the relationship between view's own layoutParams as follows:

enter image description here

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

A MeasureSpec encapsulates the layout requirements passed from parent to child. Each MeasureSpec represents a requirement for either the width or the height. A MeasureSpec is comprised of a size and a mode. There are three possible modes:

UNSPECIFIED

The parent has not imposed any constraint on the child. It can be whatever size it wants. 

EXACTLY

The parent has determined an exact size for the child. The child is going to be given those bounds regardless of how big it wants to be. 

AT_MOST

The child can be as large as it wants up to the specified size. 

MeasureSpecs are implemented as ints to reduce object allocation. This class is provided to pack and unpack the tuple into the int

Kishan Mevada
  • 662
  • 1
  • 6
  • 17