如何停止皮肤动画?

时间:2013-08-23 19:18:48

标签: actionscript-3 flex animation skinning flex4.7

我有一个贴有皮肤的自定义组件。
这个组件有几种不同的皮肤,它们都有不同的动画。因此,我在skinClasses中包含了动画 当组件不再在视图中时,我需要能够停止动画,以便它们不在后台运行。

如何在皮肤上调用停止功能?

我的猜测是添加两个皮肤状态:“animationState”和“idleState” 但是,在调用close()时,以下代码不会停止动画。 skinState不会改变。

package {
    import spark.components.supportClasses.SkinnableComponent;

    [SkinState("animationState")]   
    [SkinState("idleState")]

    public class AnimatedComponent extends SkinnableComponent
    {
        public function AnimatedComponent
        {
            setStyle("skinClass", MyAnimatedComponentSkin);
        }

        public function start():void
        {
            _isAnimating = true;
            invalidateSkinState();
        }
        public function close():void
        {
            _isAnimating = false;
            invalidateSkinState();
        }

        private var _isAnimating:Boolean = false;
        override protected function getCurrentSkinState():String
        {
            return _isAnimating ? "animationState" : "idleState";
        }
    }
}

1 个答案:

答案 0 :(得分:0)

这是我做的方式的一个例子(这实际上根本没有回答我的问题,但它适用于我需要的东西。希望这有助于其他人在解决类似的问题。)

我有一个带有自定义换肤标题和“停止”按钮的应用程序 我创建了一个名为MyCustomTitle的基类,它扩展了spark.components.supportClasses.SkinnableComponent,并使用样式表“main.css”将skinclass应用于它。

此外,当从浏览器加载应用程序时,Web脚本将“主题”参数传递给应用程序(this.parameters.theme)。这允许用户选择主题,这将决定皮肤/动画。

<?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"
               applicationComplete="application1_applicationCompleteHandler(event)">

    <fx:Style source="main.css" />

    <fx:Script>
        <![CDATA[
            import mx.events.FlexEvent;

            /**
             * An custom component that displays an animated Label
             */
            public var myComponent:MyCustomTitle;

            protected function application1_applicationCompleteHandler(event:FlexEvent):void
            {
                var theme:String = this.parameters.theme;                   
                switch(theme) {
                    case "red":
                        myComponent = new MyScalingTitle();                     
                        break;
                    default:
                        myComponent = new MyFadingTitle();                      
                        break;
                }
                myComponent.styleName = theme;
                myComponent.text = "Hello World";
                addElementAt(myComponent, 0);
                myComponent.init();
            }

            private function stop_clickHandler(event:MouseEvent):void
            {
                myComponent.stop();
            }

        ]]>
    </fx:Script>

    <s:layout>
        <s:VerticalLayout />
    </s:layout>

    <s:Button label="STOP" click="stop_clickHandler(event)"/>
</s:Application>

这是定义皮肤的CSS文件:

/* CSS file */
@namespace s "library://ns.adobe.com/flex/spark";
@namespace mx "library://ns.adobe.com/flex/mx";
@namespace local "*";


local|MyCustomTitle
{
    skinClass: ClassReference("MyCustomTitleBlueSkin");
}

local|MyCustomTitle.red
{
    skinClass: ClassReference("MyCustomTitleRedSkin");
}

这是“红色”皮肤:

<?xml version="1.0" encoding="utf-8"?>
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" 
        xmlns:s="library://ns.adobe.com/flex/spark">
    <!-- host component -->
    <fx:Metadata>
        [HostComponent("MyCustomTitle")]
    </fx:Metadata>

    <!-- SkinParts
    name=labelDisplay, type=spark.components.Label, required=true
    -->
    <s:Label id="labelDisplay" color="0xFF0000" />
</s:Skin>

而“蓝色”的那个:

<?xml version="1.0" encoding="utf-8"?>
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" 
        xmlns:s="library://ns.adobe.com/flex/spark" 
        xmlns:mx="library://ns.adobe.com/flex/mx">
    <!-- host component -->
    <fx:Metadata>
        [HostComponent("MyCustomTitle")]
    </fx:Metadata>

    <!-- SkinParts
    name=labelDisplay, type=spark.components.Label, required=true
    -->
    <s:Label id="labelDisplay" color="0x0000FF" />
</s:Skin>

我可以把动画放在上面的皮肤类中。对于非重复动画,这将完美无缺。但是因为这些动画循环,我需要能够在它们未被显示时调用它们上的stop()函数。由于我无法在皮肤中调用函数,因此我将动画添加到hostComponent类中。

MyCustomTitle具有皮肤所需的labelDisplay属性 此处定义动画,因为某些动画属性在所有不同主题之间共享。但是,截至目前,动画为空 这个类有init()方法来启动动画,还有一个stop()方法。

package
{   
    import spark.components.Label;
    import spark.components.supportClasses.SkinnableComponent;
    import spark.core.IDisplayText;
    import spark.effects.Animate;
    import spark.effects.animation.RepeatBehavior;

    public class MyCustomTitle extends SkinnableComponent implements IDisplayText
    {
        //Custom component that has a label and a skin

        [SkinPart(required="true")]
        /**
         * Button is required in the skin
         */
        public var labelDisplay:Label;

        //set common parameters that the animation will share
        protected var animate:Animate;      
        override protected function createChildren():void
        {
            super.createChildren();
            labelDisplay.text = _label;
            animate = createAnimation();
            if(animate != null) {
                animate.repeatCount = 0;
                animate.repeatBehavior = RepeatBehavior.REVERSE;
                animate.duration = 500;
            }
        }

        //build the animation here
        protected function createAnimation():Animate
        {
            //override to create dynamic animation
            return null;
        }

        //play the animation
        public function init():void
        {
            if(animate != null)
                animate.play([labelDisplay]);
        }

        //stop the animation
        public function stop():void
        {
            if(animate != null)
                animate.stop();
        }

        //components implements IDisplayText
        public function set text(value:String):void
        {
            _label = value;
            if(labelDisplay)
                labelDisplay.text = value;
        }

        public function get text():String
        {
            return _label;
        }
        private var _label:String;

        public function get isTruncated():Boolean
        {
            return labelDisplay.isTruncated;
        }
    }
}

最后,我可以扩展MyCustomTitle,以便它可以为每个主题设置不同的动画。

主题“红色”:

package
{
    import spark.effects.Animate;
    import spark.effects.Scale;

    public class MyScalingTitle extends MyCustomTitle
    {       
        override protected function createAnimation():Animate
        {
            var _scale:Scale = new Scale(labelDisplay);
            _scale.scaleXFrom = 0;
            _scale.scaleYFrom = 0;
            _scale.scaleXTo = 1;
            _scale.scaleYTo = 1;
            return _scale;
        }
    }
}

主题“蓝色”:

package
{
    import spark.effects.Animate;
    import spark.effects.Fade;

    public class MyFadingTitle extends MyCustomTitle
    {       
        override protected function createAnimation():Animate
        {
            var _fade:Fade = new Fade(labelDisplay);
            _fade.alphaFrom = 0;
            _fade.alphaTo = 1;
            return _fade;
        }
    }
}