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