3 Replies Latest reply on Nov 5, 2009 10:05 AM by rfrishbe

    Why isn't the DefaultItemRenderer class inherited from Skin?

    gameboyLV

      \sdks\4.0.0\frameworks\projects\spark\src\spark\skins\spark\DefaultItemRenderer.mxml

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

      <?xml version="1.0" encoding="utf-8"?>

      <!--- The default skin class for a Spark DefaultItemRenderer class. 
             
            @langversion 3.0
            @playerversion Flash 10
            @playerversion AIR 1.5
            @productversion Flex 4
      -->

      ....

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

       

      The DefaultItemRenderer.mxml is skin class for ItemRenderer.cs,but isn't inherited from  skin?

        • 1. Re: Why isn't the DefaultItemRenderer class inherited from Skin?
          David_F57 Level 5

          Hi,

           

          the item renderer class is more a layout component than a skin it just happens to be that the simplest case works almost like a skin but it is aware of simple string objects. As a renderer increases in capabilities it behaves less like a skin and more like a complex component.

           

           

          So I suppose in its most basic/default form you could loosely describe the itemrenderer as a skin but at the end of the day it isn't really.

          (just my thoughts...)

           

          David.

          1 person found this helpful
          • 2. Re: Why isn't the DefaultItemRenderer class inherited from Skin?
            rfrishbe Level 3

            That's just poor ASDoc on our part to call the DefaultItemRenderer a "skin".  As a side note, we actually made some changes to DefaultItemRenderer so it extends UIComponent now for performance reasons (see http://opensource.adobe.com/wiki/display/flexsdk/Item+Renderer+Changes ).  However, your question is still valid about why doesn't ItemRenderer, which is what we reccomend for user-created custom item renderers, extend from Skin.

             

            Just to give background on the current heirarchy, Group is the chromeless, light-weight container for holding visuals.  Both ItemRenderer and Skin extend from Group.  The ItemRenderer class adds some properties and behaviors specific to item renderers (like data, itemIndex, autoDrawBackground, selected, etc...).  The Skin class doesn't really add much extra features or behavior.

             

            In a lot of ways, item renderers and skins are very similar.  They both help define the look and feel of a component.  However, when we talk about skinning, we usually have a 1:1 mapping where a SkinnableComponent has a Skin object.  There's an explicit contract around skin parts and skin states.

             

            When we're talking about a ItemRenderers, that's not the case.  The DataGroup creates multiple ItemRenderers to display data.  Where possible we tried to have similar concepts to skin parts and skin states because the DataGroup (or List) will set certain properties on the ItemRenderer.  The property setters will try to put the ItemRenderer in a certain state or will try to find a component with a particular ID.  For instance, when the selected property is set on an ItemRenderer (whcih List does), the ItemRenderer will check to see whether it has a "selected" state defined and try to put the custom item renderer in that state.  Similarly, when the label property on an ItemRenderer is set, it'll look for a component with an id of "labelDisplay" and try to push the text down in to that component.

             

            Hope that helps explain some of the differences and similarities.

             

            -Ryan

            1 person found this helpful
            • 3. Re: Why isn't the DefaultItemRenderer class inherited from Skin?
              rfrishbe Level 3

              And to clarify one more thing, we also thought about making item renderers skinnable components (i.e.-ItemRenderer extends SkinnableComponent).  This way, everytime you were changing the look and feel of a component in Spark, you'd be following the exact same pattern.  But after we thought about it some more, that SkinnableComponent-Skinning model didn't really feel right here.

               

              With a SkinnableComponent we have a clear separation of the component properties and behavior on one side and the look and feel of the component on the Skin side.  Also, there's a clear contract we use to talk back and forth to one another.  The reason for the separation between the Skin and the SkinnableComponent is so that we can have one Button SkinnableComponent and multiple Skins for that Button which all tweak the visual appearance of it.

               

              It doesn't make sense for every component to be skinnable.  If you know what you're component is going to be and look like and don't need the extra flexibility skinning provides, then you can get rid of the extra overhead that skinning requires (like having 2 classes).

               

              With an ItemRenderer, we don't really need that separation and extra complexity.  It's really rare for someone to want to create an ItemRenderer component for a particular piece of data and want to have a separate Skin file for that ItemRenderer's look and feel.   For item renderers, the user really wants to create a custom item renderer with any extra behavior and the look and feel of the component all baked in to the same class.  Because of this, when you're creating a custom item renderer, you extend ItemRenderer, like:

               

              <s:ItemRenderer focusEnabled="false" 
                  xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"
                  autoDrawBackground="true">
                 
                  <s:Label id="labelDisplay" verticalCenter="0" left="3" right="3" top="6" bottom="4"/>

              </s:ItemRenderer>

              In general, if you want to build a custom component that isn't skinnable, you'd probably just extend Group (similar to our custom item renderer) and bake the child components and look and feel of the custom component right in.  If you want more flexibility and to build a new skinnable component, then you'd extend SkinnableComponent and create a default Skin for its appearance.

               

              Hope that helps,

              Ryan