AlBirdie
AlBirdie

Reputation: 2071

Reduce lifecycle validation calls in resizeable Flex LabelItemRenderer

I've subclassed the LabelItemRenderer class to create an expandable renderer for a spark list in my mobile app.

When the user selects an item, the renderer's size increases, additional data is shown. The renderer basically looks like this (I've removed the parts that don't matter here, so this is basically pseudo code).

public class PositionsGridRenderer extends LabelItemRenderer
{
    public function PositionsGridRenderer() {
        super();
        addEventListener(MouseEvent.CLICK, expandHandler);
    }

    protected override function createChildren():void {
        super.createChildren();

        _dg = new DataGroup();
        _dg.visible = false;
        addChild(_dg);
    }

    private function expandHandler(event:Event):void {
        if(_gridVisible) {
            if(!_detailClicked) {
                _dg.visible = false;
                _gridVisible = false;
            }
            _detailClicked = false;
        } else {
            _dg.visible = true;
            _gridVisible = true;
        }
    }

    public override function set data(value:Object):void {
        if(!value) return;

        super.data = value;

        var pos:Position = data as Position;

        label = pos.positionName;
        _dg.dataProvider = pos.positionSymbols;
    }

    protected override function measure():void {
        !_gridVisible ? measuredHeight = 30 : measuredHeight = 30 + getElementPreferredHeight(_dg);
        this.height = measuredHeight;
    }

    protected override function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void {
        setElementSize(labelDisplay, unscaledWidth, 30);
        setElementPosition(labelDisplay, 10,10);
        if(_gridVisible) {
            setElementSize(_dg, unscaledWidth, getElementPreferredHeight(_dg));
            setElementPosition(_dg, 0, 30);

        } else {
            setElementSize(_dg, unscaledWidth, 0);
        }

        invalidateSize();
    }
}

}

Works as expected, I'm just wondering if there's a way to reduce the amount of validation calls this renderer does when I expand it. If it is clicked to be expanded the layoutContents and measure functions are both called three times in the following order: layoutcontents -> measure, layoutcontens -> measure, layoutcontents -> measure.

I'd understand them being called once because I invalidate the size, but three times seems odd. Does anyone know why this is happening, or maybe even how to prevent this from happening?

Upvotes: 0

Views: 395

Answers (1)

JeffryHouser
JeffryHouser

Reputation: 39408

The real question was why is the component going through three full renderer cycles? After some disussion, this is what we came across:

  1. The first time the invalidate cycle is triggered is when a mouse down, or possibly a touch begin event occurs. This puts the component into the hover state; which causes a visual change in the component.
  2. The second time the invalidate cycle is triggered is when the item is selected. This puts the renderer in the down state; causing a different visual indicator to be drawn.
  3. The third invalidate cycle is caused by the component's own code; when layoutContents() calls invalidatesize()

Upvotes: 1

Related Questions