Please excuse my capitlization below; I'm not yelling, I'm
emphasizing.

> I'm not sure what you're trying to say. onLayout() does indeed set the size
> of its children, and it's using dimensions that were previously determined.
> onLayout() does not do any measurements itself, nor is it documented
> anywhere as doing so, as far as I know.
>
> 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()
>
> Right. But again, how is that different from what the documentation says?
> You quote the documentation for onLayout that says that it should "assign a
> size and position to each of its children", then seem surprised when all it
> does is assign a size to each of its children.

Let's make it really simple...

#1 Here's what View's javadoc currently says:

View.onMeasure: "Measure the view and its content to determine the
measured width and the measured height. This method is invoked by
measure(int, int) and should be overriden by subclasses to provide
accurate and efficient measurement of their contents."
View.onLayout:  "Called from layout when this view should assign a
size and position to each of its children. Derived classes with
children should override this method and call layout on each of their
their children."

#2 Here is what it _sounds_ like they do:

View.onMeasure: "Measure the size of this View. If you need to measure
the size of its children, then so be it."
View.onLayout:  "Now that we have measured the size of this View,
calculate the size and position of each of its children to fit within
the size of this View, and assign those values through the layout()
method."

#3 And apparently here is a version of what they _actually_ do:

View.onMeasure: "Measure the size of this View. Also, compute a size
and position for all of its children."
View.onLayout:  "Call layout() on each of the children with the size/
position information that has ALREADY BEEN CALCULATED."

----------------

OK, here's my problem with this onMeasure/onLayout design, and maybe
I'm mistaken somehow.  If #3 is the real scenario, then WHY IS THERE
AN ONLAYOUT METHOD THAT DERIVED CLASSES SHOULD OVERRIDE in the first
place?  There's no need for derived classes to change the
functionality of onLayout. Of course layout managers will override
onMeasure().  But, why have a public onLayout() method, if onLayout()
always does this:

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int
b) {
        //  The layout has actually already been performed and the
positions
        //  cached.  Apply the cached values to the children.
        int count = getChildCount();

        for (int i = 0; i < count; i++) {
            View child = getChildAt(i);
            if (child.getVisibility() != GONE) {
                ** RelativeLayout.LayoutParams st =
                        (RelativeLayout.LayoutParams)
child.getLayoutParams();
                child.layout(st.mLeft, st.mTop, st.mRight,
st.mBottom);
            }
        }
    }

There is NO NEED for the above method to be replicated by all
classes.  I put a ** next to the one part that would have to be
changed; one would need a generic LayoutParams, not specifically
RelativeLayout's.

Basically, all layout managers would override onMeasure() to determine
their size and the size of their children.  Why not have the above
method inside of View itself?  Have a mLeft/mTop/mRight/mBottom in the
base LayoutParam class.  In this scenario, onMeasure determines the
size and position of both itself, and assigns mLeft/mTop/mRight/
mBottom to all of its children.



> > 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.
>
> Quoted from your post that started this thread, emphasis mine:
>
> *According 
> to>>>http://developer.android.com/guide/topics/ui/custom-components.html:*
> >>> * onMeasure(int, int)     Called to determine the size requirements**for 
> >>> this
> >>> *
> >>> * view and all of its children.*

Yes, I see that there... sorry, itisn't in the regular View.onMeasure
javadoc which I was looking at. I think that the doc onMeasure is
fine, it's the onLayout that's causing the confusion.  The
clarification in onLayout's documentation would fix the confusion:
"onLayout does not compute the size/position of its children, but only
assigns them the values that were computed in onMeasure."


> > 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.
>
> Not the view itself, but the view *and its content*. That means its
> children. Perhaps the Javadoc for ViewGroup should explicitly state that, so
> that all these layout classes don't inherit the default javadoc from View,
> which of course only mentions "content", but not "children".

It is understood that content means children. As is my continued
point, if it really is the case, then it should be stated in the
onMeasure() javadoc that onMeasure() is the appropriate place to
compute the values that will be used by onLayout(), OR update onLayout
() to say that the values were already computed and should not be
computed in onLayout().


> The reason for having onMeasure and onLayout as separate steps is because
> you need to know what all the views' size constraints are before you can lay
> them all out. This is especially true if you have several levels of nested
> layouts with their sizes all set to WRAP_CONTENT. If you have a WRAP_CONTENT
> LinearLayout for example, you will need to measure the children before you
> can layout the LinearLayout itself.

Please see above paragraph; is it necessary for all derived classes to
implement onLayout()?  Why not just have View implement onLayout which
does the very thing, using the LayoutParams just like RelativeLayout
does?


> Well, you couldn't really do it in the constructor, because in the
> constructor the child views won't have been attached to the view yet.
> And really, onMeasure() is where you should determine the size, per the
> documentation. Or at least, that's where you'd call setMeasuredDimenstion().
> If your View can calculate its size ahead of time, then it certainly is free
> to do that, as long as onMeasure() still does what it is supposed to do.
>
Agreed, that was in reponse to Romain's response about being able to
calculate the values at any point.  And although you CAN calculate the
values anywhere, the framework itself should follow a certain pattern.
If your View calculates its size ahead of time, or in different spots,
then what happens when it gets subclassed?

--~--~---------~--~----~------------~-------~--~----~
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