1

I've been trying to get FXG to work in my Flex app, it works and renders fine but what I'm trying to accomplish is a sort of a gallery with data about the images in a database. I used to be able to use <s:Image source=/path/{variable_name}> but now I have to import the FXG files and can't use <s:Image> anymore. Here I can display a static FXG image:

<?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"
        xmlns:fxg="assets.fxg.*"
        tabBarVisible="false" title="{data.name}">

    <fxg:megapicture001 x="118" y="27" width="338" height="519"/>

    <s:Label x="78" y="43" text="{data.name}"/>

    <s:navigationContent>
        <s:Button icon="@Embed('assets/home.png')" click="navigator.popView()"/>
    </s:navigationContent>

</s:View>

Trying to do <fxg:{data.picturename} /> blows up.

approxiblue
  • 6,982
  • 16
  • 51
  • 59
soffi
  • 11
  • 1

1 Answers1

1

You can't import and use the FXG elements stand alone since they aren't display objects. My take was to wrap them in a UIComponent container. This class will probably end up as part of the Flextras Mobile Component set in our next update sometime early next year most likely:

package com.dotcomit.utils
{
    import flash.display.DisplayObject;
    import flash.display.Sprite;

    import mx.core.UIComponent;

    public class FXGImage extends UIComponent
    {
        public function FXGImage(source:Class = null)
        {
            if(source){
                this.source = source;
            }
            super();
        }

        // this will tell us the class we want to use for the display
        // most likely an fxgClass
        private var _source : Class;
        protected var sourceChanged :Boolean = true;

        public function get source():Class
        {
            return _source;
        }

        public function set source(value:Class):void
        {
            _source = value;
            sourceChanged = true;
            this.commitProperties();
        }

        public var imageInstance : DisplayObject;

        // if you want to offset the position of the X and Y values in the 
        public var XOffset :int = 0;
        public var YOffset :int = 0;

        // if you want to offset the position of the X and Y values in the 
        public var heightOffset :int = 0;
        public var widthOffset :int = 0;


        override protected function createChildren():void{
            super.createChildren();
            if(this.sourceChanged){
                if(this.imageInstance){
                    this.removeChild(this.imageInstance);
                    this.imageInstance = null;
                }

                if(this.source){
                    this.imageInstance = new source();
                    this.imageInstance.x = 0 + XOffset;
                    this.imageInstance.y = 0 + YOffset;
                    this.addChild(this.imageInstance);
                }
                this.sourceChanged = false;

            }
        }

        override protected function commitProperties():void{
            super.commitProperties();
            if(this.sourceChanged){
                // if the source changed re-created it; which is done in createChildren();
                this.createChildren();
            }
        }

        override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{
            super.updateDisplayList(unscaledWidth, unscaledHeight);
            if(unscaledHeight != 0){
                this.imageInstance.height = unscaledHeight + this.heightOffset;
            }
            if(unscaledWidth != 0){
                this.imageInstance.width = unscaledWidth + this.widthOffset;
            }
        }

    }
}

You can use it something like this:

<utils:FXGImage id="fxgImage" source="assets.images.mainMenu.MainMenuBackground" height="100%" width="100%" />
JeffryHouser
  • 39,401
  • 4
  • 38
  • 59
  • and for this I need the com.dotcomit.utils from Flextras.com ? – soffi Nov 24 '11 at 21:46
  • No. A package name/location just refers to the directory that the class file is in. Put the source above in the directory "com/dotcomit/utils" and you can use it as is. Or put it in your own directory and change the package name. – JeffryHouser Nov 24 '11 at 22:27
  • thanks so much, but bear with me. I'm a complete noob and I'm just not wrapping my head around this. I've created the package and place this file in it (with an .mxml ending but I don't think it matters). Flash Builder recognizes it and code completes as I start to use the package. On running I get: `1046: Type was not found or was not a compile-time constant: FXGImage.` – soffi Nov 25 '11 at 00:07
  • The file is an ActionScript only file, so it should have a .as extension. The file name should match the class name, so name the file FXGImage.as . Regarding your MXML problem, it also sounds like you didn't import the package in your MXML. You'll have to add a namespace at the top level tag, something like: xmlns:utils="com.dotcomit.utils.*" . – JeffryHouser Nov 25 '11 at 03:36
  • thanks! It runs :) now all I am struggling with is getting my picture name from the DB `` do I have to escape it somehow? – soffi Nov 25 '11 at 16:44
  • The source needs a fully qualified class name. If you have the class name as a string you can use this: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/utils/package.html#getQualifiedClassName%28%29 . – JeffryHouser Nov 25 '11 at 16:57