Вот пример того, как я это сделал (это на самом деле не ответил на мой вопрос на всех, но он работал на то, что мне было нужно. Надеюсь, что это помогает кто-то борется с подобной проблемой).
У меня есть приложение с пользовательским скином заголовком и кнопкой «СТОП».
Я создал базовый класс с именем 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;
}
}
}
Я думаю, что я нашел более практичный подход. Вместо того, чтобы использовать скин, я просто создал baseComponent, который содержит требуемые дочерние элементы/функции, а затем расширил его более сложным компонентом, который содержит всю анимацию и макет. Это работает для меня, однако было бы неплохо узнать, есть ли способ вызвать функцию на коже ... – Karmacon
Вы можете отправить код, ответивший на вашу проблему как ответ, чтобы другие пользователи могли воспользоваться? – yams