Reduzca las llamadas de validación del ciclo de vida en Flex LabelItemRenderer redimensionable

He subclasificado el 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 y 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?

preguntado el 28 de agosto de 12 a las 13:08

I'm unclear how the renderer is resized from your post. Is it like a window, where the user clicks and drags to set some new size? Or is it some fixed option that switches between two separate sizes on the click of a button? -

It is fixed. See the renderer has an initial size of 30. Take a look at the measure() function. When the grid (the optional data to be shown) is not visible, the renderer's size remains at 30. When the grid is shown (toggled by the expandHandler() function), the renderer's size increases to the initial size (30) plus the preferred height of the grid. -

I know you said this was psuedo-code; but shouldn't the 'override' be before the protected, not after? Is 'super' being called for layoutContents and/or measure? If you invalidateSize() in layoutContents, wouldn't that trigger a new validation cycle every time the component is redrawn? A lot of interactions can invalidateDisplayList(); but I don't see it you doing it manually so I'm not clear what is causing it. -

En realidad, el override can stand either before or after the access modifiers. I usually write them before as well, but the code is from a colleague who does it like this. Makes no difference though. No, super is not called for either measure or layoutContents. The code basically resembles the exact renderer, what I left out are just parts that don't matter for this "issue" such as drawing the background or other parts of the renderer aside the detail grid (i.e. another detail group below the grid). Yes, the invalidateSize does trigger another cycle, which is fine and actually required -

Could your third renderer cycle be a TouchBegin (or mouseOver?) event? I think that touchBegin causes a hover style to display, which invalidatesDisplayList(). Then the selection will cause a 'selected' style to display; which also calls invalidatesDisplayList. -

1 Respuestas

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()

Respondido 28 ago 12, 20:08

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.