8 Replies Latest reply on Mar 30, 2011 3:05 AM by jpwrunyan

    setActualSize() does not work in NavigatorContent component

    jpwrunyan Level 1

      I think I must be missing something basic but here goes:

       

      Up until now I have been implementing custom classes (in this case, sub-views for a tabbar&viewstack) from the Container class.

      But on this project I would like to use the NavigatorContent because we won't be using halo anymore.

      The problem is that as soon as I convert the custom component (written in AS) from Container to NavigatorComponent, the child components don't get sized properly.  (please note, I had to change all addChild() to addElement()).

       

      I size and position the child components inside of updateDisplayList() using move() and setActualSize().

      The child components are positioned correctly, but they are not sized correctly.

      They appear to be getting sized according to their getExplicitOrMeasuredWidth/Height() methods.

      What is going on?

        • 1. Re: setActualSize() does not work in NavigatorContent component
          Flex harUI Adobe Employee

          Is the default layout doing the sizing?

          • 2. Re: setActualSize() does not work in NavigatorContent component
            jpwrunyan Level 1

            Yeah, in the end that was the problem.  The spark components prefer letting the layout object size everything.  The default layout object is BasicLayout so that is why move() was working but not the setActualSize().  Once I dug into the BasicLayout, I saw that it was indeed sizing the components according to their measuredWidth/Height.

             

            I found a work-around which was to set layout = new LayoutBase()

             

            Then the logic inside of the parent component's updateDisplayList() doesn't get over-ridden since LayoutBase itself does nothing.

            Not sure how I feel about this... but I don't see how I can alternatively make a custom layout for my view work.  I need to refer to the child components by reference because they are sized specifically that way.  How can you do this with a custom layout object?

            • 3. Re: setActualSize() does not work in NavigatorContent component
              Flex harUI Adobe Employee

              You can do pretty much anything you want in a custom layout.  You could do a

              compass layout by expecting four parts with certain ID's like north, south,

              east, west.

              • 4. Re: setActualSize() does not work in NavigatorContent component
                jpwrunyan Level 1

                Right, but that's the thing, layout seems to assume some predictable procedural "rule" which is not representative of most GUI's I have to convert.

                I know one easy and correct answer is just to use groups since most real-world layouts can be broken down into horizontal/vertical list regions.

                But I don't want to spam groups in mxml.  I would rather do this as lightweight as possible in actionscript, preserving the original code as much as reasonably possible.

                 

                Some components have a static width/height/and/or position which I can set in createChildren() with no problem using BasicLayout.

                But other specific components need their widht/height/and/or position modified based on the dynamic unscaledWidth/Height of their parent container.

                 

                In the "old way" of doing things, I just sub-classed Container and put all this logic in its updateDisplayList().  This was convenient and easy since I already had references for these child components for eventListeners and other control logic.

                 

                I don't see how I can achieve the same thing by inserting a layout.  I would have to tell this layout class to position child #1, 2, and 3 this way, child #4 this way, child #5 this way... etc.  Instead of positioning according to reference, I am positioning according to index.  I think it is going to make the code harder to read, maintain, and less robust.

                 

                I *could* make the child components public and access them in a sub-classed LayoutBase by referencing the target property, but that means making all the child components public...

                maybe I should use an internal class???

                 

                Upon reflection, the name/id idea you suggested may be the best way to go...

                • 5. Re: setActualSize() does not work in NavigatorContent component
                  Flex harUI Adobe Employee

                  Lots of folks "mis-used" MX Container and Canvas by using it as a bas"e

                  class for a known set of children.  Containers are really for an "arbitrary

                  set of children, where in MXML you might declare the container and then some

                  children in it.

                   

                  If you have a more explicit contract and custom layout and the children

                  aren't really going to change from instance to instance, then I'd just start

                  with UIComponent.

                  • 6. Re: setActualSize() does not work in NavigatorContent component
                    jpwrunyan Level 1

                    'Containers are really for an "arbitrary

                    set of children, where in MXML you might declare the container and then some

                    children in it.'

                     

                    Wait, you have lost me.  How is sub-classing container and adding children programmatically in actionscript different than using a container tag in mxml with other nested mxml child tags in it?  The way I read that, it sounds like I would be doing exactly the same thing.

                     

                    I understand the argument against sub-classing Canvas and the argument in favor of sub-classing UIComponent.  Many of the components I need to convert are already sub-classed from UIComponent, so no changes there except changing mx child components to spark components.

                     

                    But back to the "mis-use" thing, let's ignore Container and consider a similar situation for Panel (another commonly sub-classed AS component that I will need to convert into Spark), what should I do there?  Again, the original layout logic is already inside the updateDisplayList() of mx:Panel, but if I move it to the new Spark Panel it's the same problem as in my original post, right?  Was this also a "mis-use" of Panel?  Should the contents have been implemented in a UIComponent and then have that added as the child of the Panel (or Container, NavigatorContent, etc)?

                     

                    I really want to get this right.  Is this covered at length in the documentation somewhere?

                    • 7. Re: setActualSize() does not work in NavigatorContent component
                      Flex harUI Adobe Employee

                      It depends on how "arbitrary" the set of children are.  If you are always

                      going to create the same set of children in each instance, then there isn't

                      that much advantage to using a Container or Canvas.  It also matters what

                      percentage of the Container and Canvas code you are using.  I would see lots

                      of Canvas with scrollPolicy set to "off".   That's definitely a waste.

                       

                      In Spark, I think the same rules apply, but because the architecture is more

                      segmented, you probably won't be wasting as much code, so it becomes more

                      reasonable to subclass a SkinnableContainer.  If all you want from Panel is

                      a header with text, but you're going to override everything else, then just

                      put a header with text in the skin.

                       

                      I don't think it is documented anywhere, it is just about efficiency vs

                      optimization.  MXML subclassing is easy and quick, but isn't going to be as

                      performance optimized as knowing the code and picking the base classes and

                      implementations that waste the least code.

                      • 8. Re: setActualSize() does not work in NavigatorContent component
                        jpwrunyan Level 1

                        Thank you!  I've found this discussion very helpful!