Actionscript 3 减少可调整大小的Flex LabelItemRenderer中的生命周期验证调用

Actionscript 3 减少可调整大小的Flex LabelItemRenderer中的生命周期验证调用,actionscript-3,apache-flex,air,flex4,itemrenderer,Actionscript 3,Apache Flex,Air,Flex4,Itemrenderer,我对LabelItemRenderer类进行了子类化,为我的移动应用程序中的spark列表创建了一个可扩展的渲染器 当用户选择一个项目时,渲染器的大小会增加,并显示其他数据。渲染器基本上是这样的(我删除了这里不重要的部分,所以这基本上是伪代码) } 正如预期的那样工作,我只是想知道是否有一种方法可以减少此渲染器在扩展时执行的验证调用量。 如果单击以展开,则会按以下顺序调用layoutContents和measure函数三次:layoutContents->measure,layoutconten

我对
LabelItemRenderer
类进行了子类化,为我的移动应用程序中的spark列表创建了一个可扩展的渲染器

当用户选择一个项目时,渲染器的大小会增加,并显示其他数据。渲染器基本上是这样的(我删除了这里不重要的部分,所以这基本上是伪代码)

}

正如预期的那样工作,我只是想知道是否有一种方法可以减少此渲染器在扩展时执行的验证调用量。 如果单击以展开,则会按以下顺序调用
layoutContents
measure
函数三次:layoutContents->measure,layoutcontens->measure,layoutContents->measure

我可以理解他们被打了一次电话,因为我认为尺寸无效,但三次似乎很奇怪。
有人知道为什么会发生这种情况,或者甚至知道如何防止这种情况发生吗?

真正的问题是为什么组件要经历三个完整的渲染器周期?经过一些讨论后,我们发现:

  • 第一次触发失效循环是在鼠标按下或可能发生触摸开始事件时。这将使组件处于悬停状态;这会导致组件中的视觉变化
  • 第二次触发失效循环是在选择项目时。这会使渲染器处于关闭状态;导致绘制不同的视觉指示器
  • 第三个失效周期是由组件自身代码引起的;layoutContents()调用invalidatesize()时

  • 我不清楚渲染器是如何从您的帖子中调整大小的。它是否像一个窗口,用户点击并拖动以设置新的大小?或者是某个固定的选项,点击一个按钮就可以在两个不同的尺寸之间切换?它是固定的。请参见渲染器的初始大小为30。查看
    measure()
    函数。当网格(要显示的可选数据)不可见时,渲染器的大小保持为30。当显示网格时(通过
    expandHandler()
    函数切换),渲染器的大小增加到初始大小(30)加上网格的首选高度;但“覆盖”不应该在受保护之前,而不是之后吗?对于布局内容和/或度量是否调用“super”?如果在layoutContents中使用invalidateSize(),那么每次重新绘制组件时,不会触发新的验证周期吗?很多交互都会使eDisplayList()失效;但是我看不出你是手动操作的,所以我不清楚是什么原因造成的。实际上,
    覆盖
    可以在访问修饰符之前或之后。我以前通常也写过这些代码,但代码来自这样做的同事。不过没什么区别。否,
    measure
    layoutContents
    都不调用super。代码基本上类似于精确的渲染器,我遗漏的只是与此“问题”无关的部分,例如在细节网格旁边绘制背景或渲染器的其他部分(即网格下面的另一个细节组)。是的,
    invalidateSize
    确实会触发另一个循环,这很好,实际上是必需的。您的第三个渲染器循环可能是TouchBegin(或mouseOver?)事件吗?我认为touchBegin会导致显示悬停样式,从而使DisplayList()无效。然后,选择将导致显示“选定”样式;它也调用invalidatesDisplayList。
    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();
        }
    }