Как остановить анимацию скина?

У меня есть пользовательский компонент с прикрепленной к нему оболочкой.
Для этого компонента есть несколько разных скинов, и все они анимированы по-разному. Для этого я содержал анимацию с классами скинов.
Когда компонент больше не отображается, мне нужно остановить анимацию, чтобы она не работала в фоновом режиме.

Как я могу вызвать функцию остановки на коже?

Я предполагал добавить два состояния скина: 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 ответ

Вот пример того, как я это сделал (на самом деле это вообще не отвечает на мой вопрос, но это сработало для того, что мне было нужно. Надеюсь, это поможет кому-то еще бороться с подобной проблемой).

У меня есть приложение с настраиваемым заголовком и кнопкой "STOP".
Я создал базовый класс под названием MyCustomTitle который расширяется spark.components.supportClasses.SkinnableComponentи использовал таблицу стилей "main.css", чтобы применить к ней класс skinclass.

Кроме того, когда приложение загружается из браузера, веб-скрипт передает в приложение параметр "theme" (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;
        }
    }
}
Другие вопросы по тегам