Search code examples
flashapache-flexactionscripttree

Flex dynamically changing tree node height


I want to have a tree node renderer which act as follow:

  • Clicking on it change the node height.

I have tried as follow : to create a custom class derived from UIComponent and then insert it inside the tree node renderer, but because of some reason it doesn't work as I expected.

Here's the code:

package
{
    import flash.display.Sprite;
    import flash.events.MouseEvent;

    import mx.controls.Tree;
    import mx.core.UIComponent;

    public class Expander extends UIComponent
    {
        public var expanded : Boolean = false;

        public function Expander()
        {
            super();
            this.redraw();
            this.addEventListener( MouseEvent.CLICK, onClick );
        }

        private function redraw( newWidth : Number = 60, newHeight : Number = 20 ) : void
        {
            this.graphics.clear();
            this.graphics.beginFill( 0x0000FF, 0.7 );
            this.graphics.drawRect( 0, 0, newWidth, newHeight );
            this.graphics.endFill();
        }

        private function onClick( e : MouseEvent ) : void
        {
            e.stopImmediatePropagation();
            colapseExpand();
        }

        private function colapseExpand() : void
        {
            expanded = ! expanded;
            if( expanded )
                redraw( this.width, 100 );
            else
                redraw();

            ( parent as Tree ).invalidateSize();

        }
    }
}

Here is the renderer class code:

<?xml version="1.0" encoding="utf-8"?>
<s:MXTreeItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" 
                      xmlns:s="library://ns.adobe.com/flex/spark" 
                      xmlns:mx="library://ns.adobe.com/flex/mx"
                      xmlns:lx="*">

    <s:states>
        <s:State name="normal" />            
        <s:State name="hovered" />
        <s:State name="selected" />
    </s:states>
    <s:HGroup left="0" right="0" top="0" bottom="0" verticalAlign="middle">
        <s:Rect id="indentationSpacer" width="{treeListData.indent}" percentHeight="100" alpha="0">
            <s:fill>
                <s:SolidColor color="0xFFAFFF" />
            </s:fill>
        </s:Rect>
        <s:Group id="disclosureGroup">
            <s:BitmapImage source="{treeListData.disclosureIcon}" visible="{treeListData.hasChildren}" />
        </s:Group>
        <s:BitmapImage source="{treeListData.icon}" />
        <s:Label id="labelField" text="{treeListData.label}" paddingTop="2"/>
        <lx:Expander width="100%">

        </lx:Expander>
    </s:HGroup>
</s:MXTreeItemRenderer>

The custom class is noted as lx:Expander width="100%".


Solution

  • What you want to do is create a tree with variableRowHeight="true" and then within your item renderer you can use states to 'expand' the item renderer:

    <?xml version="1.0" encoding="utf-8"?>
    <s:MXTreeItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" 
                          xmlns:s="library://ns.adobe.com/flex/spark" 
                          xmlns:mx="library://ns.adobe.com/flex/mx"
                          xmlns:lx="*">
    
        <s:states>
            <s:State name="normal" />            
            <s:State name="hovered" />
            <s:State name="selected" />
        </s:states>
        <s:HGroup height.selected="75">
            <s:Label text="Not expanded" text.selected="EXPANDED!" />
        </s:HGroup>
    </s:MXTreeItemRenderer>
    

    This should expand when the item renderer is selected, but I didn't test it. Your tree probably needs to have the property 'selectable=true' or you can always change state manually within a click event in the item renderer.