2013-08-23 9 views
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"; 
     } 
    } 
} 
+0

Я думаю, что я нашел более практичный подход. Вместо того, чтобы использовать скин, я просто создал baseComponent, который содержит требуемые дочерние элементы/функции, а затем расширил его более сложным компонентом, который содержит всю анимацию и макет. Это работает для меня, однако было бы неплохо узнать, есть ли способ вызвать функцию на коже ... – Karmacon

+0

Вы можете отправить код, ответивший на вашу проблему как ответ, чтобы другие пользователи могли воспользоваться? – yams

ответ

0

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

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

Кроме того, когда приложение загружается из браузера, веб-скрипт передает приложение «тема» в приложение (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> 

Я мог бы поместить анимацию в кожу cl задницы выше. Это будет отлично работать для не повторяющейся анимации. Но поскольку эти циклы анимации, я должен иметь возможность называть функцию 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; 
     } 
    } 
}