2011年1月27日 星期四

以SWF為Skin的程式設計

預期開發功能
1.Flash主程式與視覺外觀部份分離
2.外觀部份為以Flash IDE設計輸出swf檔案,當作主程式外觀Skin
3.Skin部份,設計師可任意排列物件
4.各個Skin,允許部份元件不存在
5.在程式進行當中,可任意更換Skin

一.Skin Loader
在利用Loader載入外部swf當作skin時,因為要當作skin用的swf內必定都會有著相同的物件名稱。例如skin01.swf與skin02.swf內都會有著同為bg的物件,這時在設定loader的LoaderContext時需設定其
context.applicationDomain = new ApplicationDomain(ApplicationDomain.currentDomain);
讓載入的物件Class屬於主體ApplicationDomain下的子系,才能讓每次載入不同swf的Class都能生效
如果使用
context.applicationDomain = ApplicationDomain.currentDomain;
會讓所有的Class都掛在主體ApplicationDomain下,這時後當重新載入新的swf時,檢查到ApplicationDomain下該物件名稱Class已經存在,則會使用原有的Class,所以新載入的swf內同名物件永遠無法載入,只會一直載入舊有的Class
就無法達到動態換Skin的作用


var loader:Loader = new Loader();
var request:URLRequest = new URLRequest(_swfPath);
var context:LoaderContext = new LoaderContext();
context.applicationDomain = new ApplicationDomain(ApplicationDomain.currentDomain);
loader.load(request,context);

二.Skin內使用物件Class設計
在Skin內要用到的物件,在設計Class時,不要在建構子內放置物件的初始化動作
(因為產生物件時,可能還沒有實體內容載入),而是將初始化的動作放在一個如
init()的public method內,在確認物件存在的狀態再執行init()即不會出錯


public function Banner(){}
public function init():void {
    setView();
    setListener();
}
private function setView():void {}
private function setListener():void {}

三.Skin Swf在Flash IDE上的設定
1.設定一個AssetContainer,用來設計Skin Layout
通常利用loader載入swf當作library來使用物件,都是利用在物件上linkage設定Class後來取得物件使用,但若這樣在程式裡產生物件使用,Layout部份,就需要寫在程式碼裡去做排列,但這樣就無法讓視覺設計去自行設計版面排列。

可以在fla內設定一個MovieClip當作AssetContainer來用,設計師在這個Container內排列所要的物件,與所要的排列方式,
透過loader載入swf後,取得這個AssetContainer物件的Class,再由這Class內,透過getChildByName,取得所有物件,各物件即已經存在有位置大小等屬性


在Fla的library內設定AssetContainer Linkage Class

var AssetContainer:Class=loader.contentLoaderInfo.applicationDomain.getDefinition(className)  as  Class
_assetLib = new AssetContainer();
mybg=_assetLib.getChildByName("bg");
mybg.init();

2.在Linkage對物件設定Class時,建議都在Class上指向完整Clss,Base Class都是MovieClip
若有需要用到相同物件,因為Class只能指定給一個物件,若有其他需要,可以extends Class出來使用即可

3.繼承自Components的元件需更改元件Linkage Class
若元件繼承自Components,在將component拉到library內後,在components上的linkage的Class改成自訂Class name
例如自己設記一個繼承自List元件的Class MyList,在Fla內需先把List元件拉入Library內,
再修改List元件的linkage的Class為MyList

四.主程式
1.物件參考變數設定
在主程式中,用來當作物件參考的變數,在重新載入Skin後即會失效
要讓物件參考變數再度指向物件參考需透過getChilByName取得才能保證取到物件

例如
在swf內有一個 instance為book的Book物件
當重新載入skin時,這個book變數並不會自動指向新取代而來的物件
需要透過
book=app.getChildByName("book")來讓變數指到實體的物件

2.不同SKin允許部份元件不存在
可能會需要在不同的Skin中允許部份的元件不存在或不使用
在可能會因為物件不存在而造成錯誤的地方,先用
if(obj!=null)做檢查再執行