- 論壇徽章:
- 0
|
1.概述 本文介紹了Gumbo的皮膚框架原理。不象MX的skinning僅是一個(gè)簡(jiǎn)單的圖形操作,Gumbo的skin是一個(gè)綜合的、可以包含多個(gè)元素(比如圖形元素,文本、圖片、轉(zhuǎn)換等),主要亮點(diǎn)如下: . 所有可視特征,包括layou都可以在skin中控制。 . 所有的skin保持簡(jiǎn)單、一致,Button的皮膚與List Item的皮膚可以是一樣的 . 通過skin parts可以進(jìn)行皮膚的組合 . 通過配置文件描述可以容易創(chuàng)建和控制
2.使用場(chǎng)景 最常用場(chǎng)景: 有一個(gè)控件,比如Button,不通過任何ActionScript代碼,只用創(chuàng)建一個(gè)新的ButtonSkin ,因?yàn)閟kin 文件是MXML,設(shè)計(jì)人員很容易進(jìn)行設(shè)計(jì)皮膚。
其它場(chǎng)景: 開發(fā)人員創(chuàng)建一個(gè)自定義組件,但可以自定義皮膚。通過繼承SkinnableComponent即可。 設(shè)計(jì)人員通過修改CSS就可以改變應(yīng)用程序的皮膚。
3.詳細(xì)描述 每個(gè)組件包含四個(gè)概念:model, skin, controller和view-specific logic(可視化描述邏輯)。
model 包含組件的屬性和業(yè)務(wù)邏輯。比如Range model的屬性有:minimumValue, maximumValue, stepSize等。方法有:畫線。model 不能包含任何可視化或行為信息。
skin 定義了組件的可視化元素。
controller 是skin和model的接口。它具有幾個(gè)關(guān)鍵功能: . 定義組件行為,比如:Button控制器具有mouse事件處理邏輯。 . 定義組件的可視化狀態(tài) . 定義組件的組成部分。比如一個(gè)scrollbar控制器具有4部分:up arrow, down arrow, thumb, 和track。
view-specific logic描述skin中不同組件的位置和大小,比如HScrollBar 和 VScrollBar具有不同的可視描述邏輯,決定thumb的位置。為了通知scrollbar,必須重載其邏輯。
skinnable componen在編程和運(yùn)行期間,其皮膚都可以改變。
4.組裝 . model 和 controller可以用ActionScript編寫。 . model和controller有時(shí)并不容易區(qū)分,尤其當(dāng)model是UI組件時(shí)。 . skin以MXML格式編寫 . view-specific logic可以寫在skin文件中,但是絕大多數(shù)時(shí)候,logic應(yīng)該放到組件中去,或者是組件的一個(gè)子類,比如ScrollBarBase->HScrollBar 或 ScrollBarBase->VScrollBar. . 對(duì)于skinnable組件, 通過 CSS與skins關(guān)聯(lián)。
其關(guān)系如下
 左邊的綠箭頭表示繼承關(guān)系,紅箭頭表示CSS轉(zhuǎn)換。
5.在skins中編碼 VS 在組件中編碼 通常,應(yīng)該把所有的可視邏輯放在skin中,尤其是想做成可定制的。但是,這很難清楚的劃分。 view-specific logic 可以放在skin中,也可以放在組件中。 一般來講,在多個(gè)skin中使用的代碼應(yīng)放在組件中, 特定的皮膚描述應(yīng)放在skin中。
比如,scrollbar擁有position和size屬性,因?yàn)閷?duì)于所有的scrollbars 都需要這二個(gè)屬性。因?yàn)槎鄠(gè)skin利用view-specific logic去定位scrollbar,因此就有了HScrollBar 子類來完成這個(gè)需求。
如果開發(fā)人員只是創(chuàng)建了一次性使用的組件,可以把view-specific logic放在skin文件中,而不是組件的子類中。
6.狀態(tài) 一些組件,象Button,可以在skin中使用狀態(tài)。組件通過SkinState 元數(shù)據(jù)定義這些狀態(tài),并在skin中定義這些狀態(tài)。
在組件中
- /**
-
* Up State of the Button
-
*/
-
[SkinState("up")]
-
-
/**
-
* Over State of the Button
-
*/
-
[SkinState("over")]
-
-
/**
-
* Down State of the Button
-
*/
-
[SkinState("down")]
-
-
/**
-
* Disabled State of the Button
-
*/
-
[SkinState("disabled")]
-
-
public class Button extends SkinnableComponent {
-
...
-
}
在skin中
- <s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark">
-
<s:states>
-
<s:State name="up" />
-
<s:State name="over" />
-
<s:State name="down" />
-
<s:State name="disabled" />
-
</s:states>
-
-
...
-
</s:Skin>
在組件中的controller 代碼決定skin的狀態(tài),通過skin中的currentState屬性定義當(dāng)前狀態(tài)。
SkinState 元數(shù)據(jù)是一種組件在skin中定義狀態(tài)的方式。如果skin沒有定義需要的狀態(tài),編譯器將拋出錯(cuò)誤。
子類可以從父類中繼承SkinState,比如: Button聲明skin states : "up", "over", "down", "disabled"。 ToggleButton 聲明skin states : "upAndSelected", "overAndSelected", "downAndSelected", "disabledAndSelected" ,并繼承了Button所有的skin狀態(tài)。
一個(gè)skin的狀態(tài)不必與組件的狀態(tài)相同。button的currentState 不必與ButtonSkin的currentState 屬性一致。button 影響skin的狀態(tài)。用戶通過設(shè)置組件的屬性影響skin的狀態(tài),比如設(shè)置toggleButton selected=true/false。
開發(fā)人員可以使用invalidateSkinState() 和getCurrentSkinState() 改變skin的狀態(tài), invalidateSkinState() 驗(yàn)證skin狀態(tài)。
例如 (Button.as):
- package spark.components
-
{
-
-
/**
-
* Up State of the Button
-
*/
-
[SkinState("up")]
-
-
/**
-
* Over State of the Button
-
*/
-
[SkinState("over")]
-
-
/**
-
* Down State of the Button
-
*/
-
[SkinState("down")]
-
-
/**
-
* Disabled State of the Button
-
*/
-
[SkinState("disabled")]
-
-
public class Button extends SkinnableComponent implements IFocusManagerComponent
-
{
-
-
...
-
-
/**
-
* @return Returns true when the mouse cursor is over the button.
-
*/
-
public function get isHoveredOver():Boolean
-
{
-
return flags.isSet(isHoveredOverFlag);
-
}
-
-
/**
-
* Sets the flag indicating whether the mouse cursor
-
* is over the button.
-
*/
-
protected function setHoveredOver(value:Boolean):void
-
{
-
if (!flags.update(isHoveredOverFlag, value))
-
return;
-
-
invalidateSkinState();
-
}
-
-
...
-
-
// GetState returns a string representation of the component's state as
-
// a combination of some of its public properties
-
protected override function getUpdatedSkinState():String
-
{
-
if (!isEnabled)
-
return "disabled";
-
-
if (isDown())
-
return "down";
-
-
if (isHoveredOver || isMouseCaptured )
-
return "over";
-
-
return "up";
-
}
-
-
...
-
-
//--------------------------------------------------------------------------
-
//
-
// Event handling
-
//
-
//--------------------------------------------------------------------------
-
-
protected function mouseEventHandler(event:Event):void
-
{
-
var mouseEvent:MouseEvent = event as MouseEvent;
-
switch (event.type)
-
{
-
case MouseEvent.ROLL_OVER:
-
{
-
// if the user rolls over while holding the mouse button
-
if (mouseEvent.buttonDown && !isMouseCaptured)
-
return;
-
setHoveredOver(true);
-
break;
-
}
-
-
case MouseEvent.ROLL_OUT:
-
{
-
setHoveredOver(false);
-
break;
-
}
-
-
...
-
}
-
}
-
}
-
-
}
待續(xù)
參考文獻(xiàn) 1.Spark Skinning (including SkinnableComponent) - Functional and Design Specification. http://opensource.adobe.com/wiki/display/flexsdk/Spark+Skinning 2.
|
|