0

我有一个带有皮肤的自定义组件。
该组件有几种不同的皮肤,它们的动画效果都不同。因此,我将动画包含在 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";
        }
    }
}
4

1 回答 1

0

这是我这样做的一个示例(这实际上根本没有回答我的问题,但它可以满足我的需要。希望这可以帮助其他人在遇到类似问题时遇到困难)。

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

此外,当从浏览器加载应用程序时,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;
        }
    }
}
于 2013-09-13T02:09:17.107 回答