Honestly, it sounds like you are trying to do things with RelativeLayout that are depending on its internal implementation. If you really have a layout that is needing to subclass from it and change how it is handling its children, I would strongly strongly encourage you to just write your own layout manager. Just copy the RelativeLayout code from the framework and modify it to work how you want, if that is the easiest thing.
I realize that app developers are going to do this kind of stuff, and as we fix bugs and add features in the implementation we will end up breaking apps like this and have do something about that... most likely we will choose to either put in compatibility code for old apps (making the class less efficient) or leave that class how it is and just add in another layout manager. But there is a chance that we could decide that the one or two apps that break are doing unreasonable things, and let them break. As an app developoer, it is in your interest to play a little safe and try to avoid relying on implementation details. 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. > > 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 > > > -- Dianne Hackborn Android framework engineer [email protected] Note: please don't send private questions to me, as I don't have time to provide private support, and so won't reply to such e-mails. All such questions should be posted on public forums, where I and others can see and answer them. --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---

