我有一个带有皮肤的自定义组件。
该组件有几个不同的蒙皮,它们的动画设置也都不同。因此,我已经包含了skinClasses的动画
当组件不再在视图中时,我需要能够停止动画,这样它们就不会在后台运行。
如何在皮肤上调用停止函数
我的猜测是添加两种皮肤状态:"animationState"one_answers"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";
}
}
}
这是我做这件事的一个例子(这实际上根本不能回答我的问题,但它满足了我的需求。希望这能帮助其他遇到类似问题的人)。
我有一个带有自定义可剥皮标题和"停止"按钮的应用程序
我创建了一个名为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;
}
}
}