actionscript-3apache-flexflex4flex4.6flex-mobile

Inheritance with Flex mxml files - screenshot attached


In a Flex mobile app I have 5 Views, handling OAuth logins through 5 different social networks - including Google+ and Facebook. The Views are being selected through the menu shown below:

enter image description here

The filenames are FB.mxml, GG.mxml, MR.mxml, OK.mxml, VK.mxml and their source code looks very similar:

<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 
        xmlns:s="library://ns.adobe.com/flex/spark" 
        viewActivate="loadInfo(event)"
        viewDeactivate="closeSWV(event)"
        title="Facebook.com">
....
            private function closeSWV(event:Event=null):void {
                _busy.visible = _busy.includeInLayout = false;
                _reload.visible = _reload.includeInLayout = true;

                stage.removeEventListener(Event.RESIZE, resizeSWV);
                if (! _swv)
                    return;
                _swv.removeEventListener(Event.COMPLETE, extractAccessToken);
                _swv.removeEventListener(LocationChangeEvent.LOCATION_CHANGE, extractAccessToken);
                _swv.removeEventListener(IOErrorEvent.IO_ERROR, closeSWV);
                _swv.removeEventListener(ErrorEvent.ERROR, closeSWV);
                _swv.dispose();
                _swv = null;
            }           

            private function resizeSWV(event:Event=null):void {
                if (! _swv)
                    return;
                // align to the right-bottom corner
                _swv.viewPort = new Rectangle(stage.stageWidth - Preferans.SCALE * width, 
                    stage.stageHeight - Preferans.SCALE * height, 
                    Preferans.SCALE * width, 
                    Preferans.SCALE * height);
            }
....
        <s:VGroup>
            <s:Label id="_first"  fontWeight="bold" text="Your name:" />
            <s:Label id="_gender" fontWeight="bold" text="Gender:" />
            <s:Label id="_city"   fontWeight="bold" text="City:" />
        </s:VGroup>

    <s:Button id="_play"
              label="Play" 
              click="startGame(event)"
              includeInLayout="false"
              visible="false" />
</s:View>

My problem is: The 5 mxml files listed above have many similar methods and variables and UI elements and only few different methods and variables.

I've tried to introduce a "base class" for them all several times already and have always given up, because it is not straightforward for mxml files (versus pure AS3 classes).

Does anybody please have an idea, how to approach this?


Solution

  • You can define an abstract class that extends the UI component that you want to use in each row of the list. In your case, it will extend View.

    package your.package{
        public class SocialAccountView extends View{
    
            // in this class you can add the generic methods
            // that you want the view to have
    
        }
    }
    

    After that, in the mxml file you can use the class you created as the main type instead of View

    <your.package:SocialAccountView
        xmlns:fx="http://ns.adobe.com/mxml/2009" 
        xmlns:s="library://ns.adobe.com/flex/spark" 
        viewActivate="loadInfo(event)"
        viewDeactivate="closeSWV(event)"
        title="Facebook.com">
    
    </your.package:SocialAccountView>
    

    With this you know that all the items in the list are of that type, and have the methods of the parent class. You can even override methods in each view.

    Regarding the UI components, the maximum abstraction level (that I am aware of) you can have with them is to build an extra component and use it in all views. Something like...

    Labels.mxml

        <s:VGroup>
            <s:Label id="_first"  fontWeight="bold" text="Your name:" />
            <s:Label id="_gender" fontWeight="bold" text="Gender:" />
            <s:Label id="_city"   fontWeight="bold" text="City:" />
        </s:VGroup>
    

    and then use it in each component like

    <your.package:Labels 
                  id="labelsComponent"/>
    

    Hope this helps.