On Mon, Jun 15, 2009 at 1:34 PM, Matt <[email protected]> wrote:
> > 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. 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. > 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. 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.* >> >> 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. 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". 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()? 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. 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. 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. 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(). I suspect that you can override onMeasure, but you have to be sure to also measure all the children (the "content"). If you only did the measurements for the view itself, then I suspect that's why it wasn't working right for you. 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). > --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---

