Search code examples
apache-flexactionscriptcustom-componentflex-spark

ActionScript creating custom component to hold two other spark components


I'm fairly new to ActionScript/Flex so I'm not entirely sure if this is even possible.

Basically I have the following block repeating several times in my code:

<s:TextInput .. \>
<s:BitmapImage .. \>

What I'm trying to do is create an ActionScript custom component so I can replace the above block everywhere in my code with:

<MyBlock\>

My best guess is I have to do this by extending spark.application?

What I have so far:

package MyPackage
{
   import spark.components.Application;

   public class MyBlock extends Application
   {
     ..
   }
..
}

I am completely at a loss as to how to combine two existing components into a new custom one, if it is even possible.

How exactly should I proceed next? Any help would be appreciated.

Thanks,


Solution

  • It is so much easier than that: for this use case you should simply extend Group. And to make things easier, write your composed component in MXML.

    Create a new file MyBlock.mxml (for instance in com/mydomain/components) and add the following code:

    <s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
             xmlns:s="library://ns.adobe.com/flex/spark">
    
        <s:TextInput .. />
        <s:BitmapImage .. />
    </s:Group>
    

    Now simply use this component:

    <c:MyBlock />
    

    where the c namespace is defined as xmlns:c="com.mydomain.components.*" at the root node of your document using this class. For example:

    <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:c="com.mydomain.components.*">
        <c:MyBlock />
    </s:Application>
    

    Now suppose you want to have a different text in each block, you'll have to expose a property. To do this, lets add a label property to MyBlock:

    <fx:Declarations>
        <fx:String id="label" />
    </fx:Declarations>
    

    To make the TextInput show what's in that variable whenever it changes, we use binding like so:

    <s:TextInput text="{label}" />
    

    The final component would look something like this:

    <s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
             xmlns:s="library://ns.adobe.com/flex/spark">
    
        <fx:Declarations>
            <fx:String id="label" />
        </fx:Declarations>
    
        <s:TextInput text="{label}" .. />
        <s:BitmapImage .. />
    </s:Group>
    

    Now you can create multiple MyBlock instances with different texts:

    <c:MyBlock label="hello" />
    <c:MyBlock label="world" />
    

    Note that if your regular use of MyBlock is more in a list-like fashion, you may want to consider using a List component with a custom ItemRenderer, rather then using MyBlock over and over again.