从弹出窗口内部调用PopUpManager.removePopUp()时,模态窗口动画中断

时间:2014-01-14 12:00:39

标签: flex flex-spark

我有一个模态窗口,我在打开和关闭时显示调整大小动画,但有时它会在关闭时闪烁。

我已将其追踪到一件事。当我在窗口外单击时,关闭动画播放正常。代码位于主应用程序中,采用mouseUpOutsideHandler方法。这是对PopUpManager.removePopUp()的简单调用。当我单击窗口内部的关闭按钮时,它会在窗口内的PopUpManager.removePopUp()方法中运行相同的完整代码close(),除非它首先闪烁。

除了从模态窗口实例中调用之外,它是完全相同的代码。看起来模态窗口逐渐淡出然后被移除然后我的移动动画被播放。请参阅代码示例。

示例:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">


<fx:Script>
    <![CDATA[
        import com.flexcapacitor.effects.popup.OpenPopUp;

        import mx.core.IFlexDisplayObject;
        import mx.managers.PopUpManager;

        protected function showPopUp():void {
            var myPopUp:MyPopUp = new MyPopUp();
            PopUpManager.addPopUp(myPopUp as IFlexDisplayObject, this, true);
            PopUpManager.centerPopUp(myPopUp);

            myPopUp.addEventListener(OpenPopUp.MOUSE_DOWN_OUTSIDE, mouseUpOutsideHandler, false, 0, true);
        }

        private function mouseUpOutsideHandler(event:Event):void {
            // does not create a flicker
            PopUpManager.removePopUp(event.currentTarget as IFlexDisplayObject);
            MyPopUp(event.currentTarget).removeEventListener(OpenPopUp.MOUSE_DOWN_OUTSIDE, mouseUpOutsideHandler);  
        }

    ]]>
</fx:Script>


<fx:Declarations>
    <fx:Component className="MyPopUp">
        <s:Panel xmlns:fx="http://ns.adobe.com/mxml/2009" 
           xmlns:s="library://ns.adobe.com/flex/spark" 
           xmlns:mx="library://ns.adobe.com/flex/mx" 
           resizeEffect="Resize"
           resize="panel1_resizeHandler(event)"
           creationCompleteEffect="{addedEffect}"
           removedEffect="{removedEffect}"
           width="400" height="200">

            <fx:Script>
                <![CDATA[
                    import mx.events.ResizeEvent;
                    import mx.managers.PopUpManager;


                    protected function close():void {
                        // when called here creates a flicker effect 
                        // it looks like the pop up is faded out and removed 
                        // and then the removed effect is played
                        PopUpManager.removePopUp(this);
                    }

                    protected function panel1_resizeHandler(event:ResizeEvent):void {
                        if (stage && !addedEffect.isPlaying) {
                            PopUpManager.centerPopUp(this);
                        }
                    }
                ]]>
            </fx:Script>

            <fx:Declarations>
                <s:Parallel id="removedEffect" target="{this}" >
                    <s:Scale3D scaleYTo="0" duration="1000" startDelay="0" disableLayout="false"
                               autoCenterProjection="true" autoCenterTransform="true"/>
                    <s:Fade alphaFrom="1" alphaTo="0" duration="500" startDelay="50"/>
                </s:Parallel>

                <s:Parallel id="addedEffect" target="{this}" >
                    <s:Scale3D scaleYFrom="0" scaleYTo="1" duration="250" disableLayout="false"
                               autoCenterProjection="true" autoCenterTransform="true"/>
                    <s:Fade alphaFrom="0" alphaTo="1" duration="200"/>
                </s:Parallel>

            </fx:Declarations>

            <s:Label horizontalCenter="0" verticalCenter="0" text="Hello World"/>
            <s:Button horizontalCenter="0" verticalCenter="30" label="Close" click="close()"/>
        </s:Panel>
    </fx:Component>
</fx:Declarations>


<s:Button label="Show Pop Up" 
          horizontalCenter="0" verticalCenter="0"
          click="showPopUp()" 
          />

1 个答案:

答案 0 :(得分:0)

可以使用来电来修复。

方法1

protected function close():void {
      //PopUpManager.removePopUp(this);
      callLater(PopUpManager.removePopUp, [this]);
}

方法2

function close(popUp:IFlexDisplayObject, endEffectsPlaying:Boolean = true) {
    if (popUp && popUp as IUIComponent && UIComponent(popUp).isEffectStarted) {
        if (endEffectsPlaying && popUp && popUp as IUIComponent) {
            EffectManager.endEffectsForTarget(popUp as IUIComponent);
        }

        // we exit out because if we continue, we would close the pop up.
        // but if we did that then when the effect ends it puts up a 
        // display object "shield" and there would be no way to close 
        // the display object shield since we removed the pop up 
        // display object that has our closing event listeners 
        return;
    }

    try {
        PopUpManager.removePopUp(popUp as IFlexDisplayObject);

    }
    catch (error:Error) {
        // sometimes the pop up is already closed or something 
        // or there's a bug in PopUpManager or EffectManager
    }
}

奖金代码

// The following code may be unrelated but it was
// in my pop up so it might be helping prevent an error
// i normally don't add unrelated code but it may help
protected function panel1_resizeHandler(event:ResizeEvent):void {
    if (stage && !addedEffect.isPlaying) {
        // to fix bug on line 505 of PopUpManagerImpl
        var popUpImp:PopUpManagerImpl = PopUpManagerImpl(Singleton.getInstance("mx.managers::IPopUpManager"));
        var popupInfo:Array = popUpImp.popupInfo;

        const n:int = popupInfo.length;
        var instanceIndex:int = -1;

        for (var i:int = 0; i < n; i++) {
            var o:PopUpData = popupInfo[i];
            if (o.owner == this) {
                instanceIndex = i;
            }
        }

        if (instanceIndex!=-1) {
            PopUpManager.centerPopUp(this);
        }
    }
}

此外,您可以查看OpenPopUp and ClosePopUp效果类是否适合您。