Pay for Hesitation: Add Sprite to Canvas (explanation)

Pages

2008年4月5日 星期六

Add Sprite to Canvas (explanation)

在Flex的架構下, Canvas是無法加入Sprite等非UIComponent的DisplayObject的!
先看下面這種用法,

var widget:Sprite = new Sprite();
addChild(widget);

當執行到以上這段的時候, 會出現以下Runtime Error,

"Type Coercion failed: cannot convert Sprite to mx.core.IUIComponent"

原因在於addChild()的參數需要是IUIComponent, 假如我們直接將Sprite轉為IUIComponent, 就會出現Runtime Error. (如果硬用"as"來做casting, 很神奇的會回傳null, 還是會失敗)

來看看, Flex的視覺元件架構中, Sprite是FlexSprite和UIComponent的parent, 這正是強迫轉型產生錯誤的原因.

UIComponent -> FlexSprite -> Sprite -> DisplayObjectContainer -> InteractiveObject -> DisplayObject -> EventDispatcher -> Object

不過也不是沒辦法達到將Sprite加入至Canvas的目的的. UIComponent下的Containers有一個read only的屬性欄位rawChildren, 它繼承IChildList!! 因此, Containers等於直接可以有自己的小孩!!
(The IChildList interface defines the properties and methods for accessing and manipulating child lists, which are subsets of a DisplayObjectContainer's children.)

當然, 我們無法直接將Sprite加入至Containers, 因為Sprite並屬於UIComponent(並沒有實作IUIComponent介面..), 但是, 別忘記Containers下面有繼承IChildList的rawChildren, rawChildren竟然也有addChild(), 於是就可以達到將Sprite加到Canvas的目的囉!

var widget:Sprite = new Sprite();
this.rawChildren.addChild(widget);

可以看看以下的Flex視覺元件架構~~
DisplayObjectContainer: DisplayObjectContainer extends InteractiveObject class and it is a base shell for all containers which adds display objects in the container shell. . DisplayObjectContainer provides some common properties like… numChildren, tabChildren etc… and methods like addChild(), removeChilld() method related to the child display object management.

FlexSprite: FlexSprite is a subclass of the Player’s Sprite class and the superclass of UIComponent. It overrides the toString() method to return a string indicating the location of the object within the hierarchy of DisplayObjects in the application. The Sprite class is a basic display list building block: a display list node that can display graphics and can also contain children.

UIComponent: UIComponent extends Sprite and it is a base class for all Interactive and non Interactive component. The UIComponent class is not used as an MXML tag, but is used as a base class for other classes.

All Visual Components like VBox, HBox, Canvas, Button etc… extends UIComponent.

沒有留言: