Search code examples
actionscript-3flex4.5mxmlflex-spark

Flex container with HTML style floating


I am using Flex 4 with Spark components to build a mobile application and I have a HGroup that I am using to contain all of my elements. When the screen loads it pulls in a small amount of text that will be displayed and loops through all the words to see if any of them are a keyword. While it is looping I am putting each word into its own label element and if the word is a keyword it changes a few styles and adds a click event to show a description about the word.

Everything runs fine but when everything is appended to the HGroup, there ends up being only one line and most of the text completely cut off because it will not wrap the content.

My Question is - Is there a way to set or extend the HGroup to allow content wrapping on its child elements?

Below are some code snippets of what I have:

MXML containers:

<s:VGroup id="answerData" width="580" height="700" horizontalAlign="center" paddingTop="5">
<s:HGroup id="theLabel" color="white" width="580" fontSize="25" paddingBottom="20" />
<s:HGroup id="theText" color="white" width="580" fontSize="25" maxWidth="580" />
</s:VGroup>

AS to create labels:

public static function setKeyWords(someText:String, theGroup:Group, theDictionary:Array, theView:Object):void {
        theGroup.removeAllElements();
        var textArray:Array = someText.split(' ');
        for(var i:int = 0, l:int = textArray.length; i < l; i++) {
            if(checkForWord(theDictionary, textArray[i].toString())) {
                var theLink:Label = new Label();
                theLink.text = textArray[i].toString();
                theLink.setStyle("color", "0xFFFF00");
                theLink.setStyle("fontWeight", "bold");
                theLink.maxWidth = 580;
                var tmpDescrip:String = theDescription;
                theLink.addEventListener(MouseEvent.CLICK, function(evt:MouseEvent):void {
                    showToolTip(tmpDescrip, theView);
                });
                theGroup.addElement(theLink);
            } else {
                var someLabel:Label = new Label();
                someLabel.maxWidth = 580;
                someLabel.text = textArray[i].toString();
                theGroup.addElement(someLabel);
            }
        }
    }

Solution

  • The issue that I was having is, I had multiple lables in a VGroup and needed them to wrap instead of extending past the containers set width. I was trying to integrate keywords into a dynamic paragraph of text. I could not use mx:Text because I needed each word to be its own component that allowed custom styling plus a mouse click even if the word was a keyword. Also the label max lines solution would not work because I am dealing with multiple lables in a VGroup and the VGroup needed to wrap its children not the label tags. I also could not use a TileGroup because it does not look right breaking a paragraph into a table looking component where each word is in its own column/row.

    The solution I used was to count each character in the label being generated and add it to a variable to determine when I need to create a new HGroup that holds the labels and sits in a VGroup. I had to do this because I cannot determine the labels width until it renders because it is generated dynamically. This could not be done because as its render point is too late for me to move everything because the user can see all of this happening which is definitely not the desired effect.

    Below is the code I used to solve this issue incase anyone else runs into this issue:

    public static function setKeyWords(someText:String, theGroup:Group, theDictionary:Array, theView:Object):void {
            theGroup.removeAllElements();
            var textArray:Array = someText.split(' ');
            var theCount:int = 0;
            var theHGroup:HGroup = new HGroup();
            var breakNum:int = 40;
            theHGroup.percentWidth = 100;
            for(var i:int = 0, l:int = textArray.length; i < l; i++) {
                theCount += textArray[i].toString().length;
                if(theCount >= breakNum) {
                    theGroup.addElement(theHGroup);
                    theHGroup = new HGroup();
                    theHGroup.percentWidth = 100;
                    theCount = 0;
                }
                if(checkForWord(theDictionary, textArray[i].toString())) {
                    theCount += 1;
                    var theLink:Label = new Label();
                    theLink.text = textArray[i].toString();
                    theLink.setStyle("color", "0xFFFF00");
                    theLink.setStyle("fontWeight", "bold");
                    theLink.maxWidth = 580;
                    //theLink.includeInLayout = false;
                    var tmpDescrip:String = theDescription;
                    theLink.addEventListener(MouseEvent.CLICK, function(evt:MouseEvent):void {
                        showToolTip(tmpDescrip, theView, 'keywords');
                    });
                    theHGroup.addElement(theLink);
                } else {
                    theCount += 1;
                    var someLabel:Label = new Label();
                    someLabel.maxWidth = 580;
                    someLabel.text = textArray[i].toString();
                    //someLabel.includeInLayout = false;
                    theHGroup.addElement(someLabel);
                }
            }
            if(theCount > 0)
                theGroup.addElement(theHGroup);
        }
    

    This may not be the most effecient way to do this but it does work and takes little time to execute on the Iphone which is what I was aiming for.