Apparently we're all reading different parts of the documentation.
And if it actually doesn't go against the paradigm of layouts in
Android, then all I'm saying is the documentation is not clear about
it.

>> No, they're not.  They are assigned in onMeasure(). Well, if you want
>> to get technical, they are calculated in onMeasure(), and assigned in
>> onLayout().
>
> How is that not what the documentation says? The documentation says
> that onMeasure "determines" the size. You say it "calculates" it.

You're missing something here, and perhaps it is my fault for not
communicating it properly.  I'm not talking about the RelativeLayout
itself, I'm talking about its children.  I was under the impression
that onMeasure() gets called to set the measured value, via
setMeasuredDimension(), and then onLayout() would layout the children
with respect to the View's dimensions as determined in onMeasure(). It
doesn't, onLayout() does not respect the value set by
setMeasuredDimension() in onMeasure(); in fact, the layout of the
children is determined in onMeasure(), not onLayout(). Since I'm
wrong, OK whatever, but I would expect the documentation to be more
clear on the matter.

The documentation for View.onMeasure(): "Measure the view and its
content to determine the measured width and the measured height". The
documentation for View.onLayout: "Called from layout when this view
should assign a size and position to each of its children."  I'm not
being stupid here: the documentation, to me, seems to imply that
onMeasure() calculates the View's size, and onLayout() calculates the
positions/sizes of the view's children. Apparently, onLayout() does
not necessarily calculate those values for the children, but only
assigns them, and those values can be calculated before the onLayout()
event occurs. Understandably, you cannot calculate a View's size
without calculating the size of its children in many Views, such as in
a RelativeLayout.

And anyways, I'm fine with having the children's size/position
calculated in onMeasure(). It's just that, if that's the case, I would
make it more explicit in the documentation.  This way, one knows that
if you override onMeasure(), you have to assign values to each child
LayoutParams.params's mLeft, mRight, mTop, and mBottom.  Then it is up
to onLayout() to use those values later. This is a perfectly fine
scenario, but it is not explicit, and not laid out in the
documentation!

> >> It's just using cached values computed in onMeasure(), which does not
> >> go against the concepts of ViewGroups as defined by the javadoc.
>
> > The size and position should be determined in onLayout.  They are not,
> > they are determined in onMeasure.  The javadoc explicitly states that
> > the size and position should be determined in onLayout.  They are not.
>
> No, the documentation explicitly says they should be *determined* in
> onMeasure. You even quoted the part of the documentation that says
> exactly that.

See above.  You say that the documentation explicitly says that the
size and position of a ViewGroup's children should be determined in
onMeasure()?  I don't see that, and I certainly didn't quote it.
Remember, I'm talking about the RelativeLayout's children, not the
size of the RelativeLayout itself.  onMeasure() does not say that the
size and position of its children are calculated, onMeasure() says
that it calculates the size of the View itself.

If you have a custom subclassed RelativeLayout, and override onMeasure
() to provide a custom measurement, the layout no longer works.  You
cannot override onMeasure() with a different size, and expect the
layout to still work correctly, as the layout will size/position its
children the way it wants, without respecting the value returned by
onMeasure().

In other words, onLayout() does not respect the measured value set by
onMeasure().

> No, the javadoc states that the size and positions should be *assigned* in
> onLayout():
> "Called from layout when this view should assign a size and position to each
> of its children"
> There is absolutely no restriction on how and when the sizes and positions
> are computed. You could very well do it in the view's constructor if you
> wanted.

Then I think this is a problem. I understand that it only says
"assigns" and not "computes".  However, the idea of computing sizes
and positions anywhere creates problems when providing custom
functionality with the framework (like subclassing).  Perhaps you
calculated every size and other attributes of some View in its
constructor.  Then why even have the event methods in the first
place?  Why have onFinishInflate(), onMeasure(), onLayout(), onSize(),
etc., if everything can be calculated in the constructor?  Why not
require setMeasuredDimension(int, int) to be called in the
constructor? If onLayout() doesn't care what onMeasure() says, then
why not just skip onLayout(), and go ahead and assign the size/
position of its children in onMeasure()?

If this point is valid, then IMHO I think that's a bad design
decision. You couldn't override the behavior.  You don't know where
certain steps happen in the chain of events (without being able to
look at the source code) just by knowing the API. One could create a
View which does all of its calculations in its constructor, and
ignores all of the events.  That would mean if anyone tried to
override the method to do their own calculations, it would fail
because they were already calculated in the constructor.




So, in the end, here are my points:

1. You cannot override onMeasure() of a RelativeLayout and provide a
different size; the children of the RelativeLayout will position
themselves however they want, without regards to your overridden
onMeasure().
2. The documentation isn't explicit in stating that onLayout() does
not have to respect the measured value set in onMeasure().
3. The documentation isn't explicit in stating that the children of a
Layout's size/position can be calculated _anywhere_, such as the
constructor, instead of in onLayout().

If the point in #3 is valid, then IMHO I think that's a bad design
decision (see above paragraph).

- Matt
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to