Flex4皮肤制作
轉自:冰山的播客 http://xinsync.xju.edu.cn/index.php/archives/2241
FLEX3.0組件可以通過CSS來控制樣式,這里的CSS和平時編寫網頁時所談及的CSS是有區別的,可以說是為FLEX量身定制的樣式表,借助ActionScript可以實現強大的顯示效果,下面的示例中會有相關介紹。
Adobe公司發布的Express Photoshop,黑色風格很令人著迷,KingnareStyle就是以它為原型制作的一款FLEX皮膚。皮膚包含的組件很多,限于篇幅,只能選取有代表性的組件做演示。下面以Button組件為例,開始FLEX皮膚制作的入門。
我們先在Flex Builder 3中新建一個項目FlexSkinTest
新建文件夾style,并在style文件夾下新建style.css文件:
雙擊打開style.css,切換到Design面板并新建一個樣式:
選擇Button組件:
按下OK后可以看到按鈕的8種狀態。便于測試,我們把背景色調整為0×333333:
切換到Source面板調整字體樣式:
Button
{
color:#AAAAAA;/*Color*/
textRollOverColor:#FFFFFF; /*text rolling over color*/
textSelectedColor:#FFFFFF; /*SelectedColor*/
disabledColor:#5A5A5A; /* disabledColor */
fontWeight:normal; /*fontweight*/
}
結果如下圖:
接下來的工作就是把按鈕的8種狀態用自定義的皮膚替換掉。
常用的實現方法有4種,我們將逐步介紹。
我們先學習KingnareStyle中Button組件皮膚的實現方法:將外部swf文件里的皮膚元件嵌入到組件樣式文件中。
嵌入swf文件中的元件
首先在style文件夾下新建文件skin.fla,背景色同樣設置為#333333。
CTRL+F8新建影片剪輯Button_upSkin,屬性設置如下:
這里最好啟用9切片,以后嵌入FLEX樣式時就不用進行9切片設置了。
關于9切片,可以參考下面圖示(引自Flex Developer Center):
將舞臺放大至400%,使用矩形工具畫一個空心矩形,坐標為(0,0),厚度為1像素,高寬均為23像素,填充色為#FFFFFF,透明度10%
再新建一個層,用同樣的方法在內部畫一個空心矩形,坐標為(1,1),厚度1像素,高寬均為21像素,填充色為#000000,透明度60%
下面填充空白區。
新建一個層,畫實心矩形,坐標為(2,2),高寬均為19像素,填充線性漸變色白色,透明度由10%至0%:
最后再加高亮框。新建一個層,畫空心矩形,坐標為(2,2),厚度為1,高寬均為19像素,填充線性漸變色白色,透明度由8%至3%
至此,圖形部分完成,再把9切片的線重新定位:
CTRL+ENTER發布程序。
Flash部分告一段落,回到FLEX的style.css中。切換到Source面板,在Button樣式中加入下面語句:
upSkin:Embed(source=”skin.swf”, symbol=”Button_upSkin”);
解釋一下,upSkin,Button彈起狀態皮膚。Embed語句,用于將外部資源嵌入程序中使用,本例中將skin.swf中的Button_upSkin元件嵌入到樣式中。
保存后切換到Design面板,會發現up狀態已經更新為我們剛才制作的元件了:
使用同樣的方法來制作其他狀態皮膚,要注意給元件賦合適的名字。最后CCS如下:
Application
{
backgroundGradientAlphas: 1.0, 1.0;
backgroundGradientColors: #333333, #333333;
}
Button
{
color: #AAAAAA;
textRollOverColor: #FFFFFF;
textSelectedColor:#FFFFFF;
disabledColor:#5A5A5A;
fontWeight:normal;
upSkin: Embed(source=”skin.swf”, symbol=”Button_upSkin”);
overSkin: Embed(source=”skin.swf”, symbol=”Button_overSkin”);
downSkin: Embed(source=”skin.swf”, symbol=”Button_downSkin”);
disabledSkin: Embed(source=”skin.swf”, symbol=”Button_disabledSkin”);
selectedUpSkin: Embed(source=’skin.swf’, symbol=’Button_selectedUpSkin’);
selectedOverSkin: Embed(source=’skin.swf’, symbol=’Button_selectedOverSkin’);
selectedDownSkin: Embed(source=’skin.swf’, symbol=’Button_selectedDownSkin’);
selectedDisabledSkin: Embed(source=’skin.swf’, symbol=’Button_selectedDisabledSkin’);
}
效果圖:
接下來我們打開FlexSkinTest.mxml文件,切換到Source面板,
添加 <mx:Style source=”style/style.css”/>
<mx:Button x=”10″ y=”10″ label=”Button”/>
換到Design面板,可以看到新加的Button組件已經應用我們的樣式了,也可以多拖幾個Button到程序中并設置不同的大小,可以發現邊緣并未因形變發生模糊,這是我們使用了9切片的結果。
可以說,我們的Button組件皮膚已經完工了。
使用Flex Skin Design Extensions for Flash CS3
我們再開始第二種皮膚制作方法。
先做準備活動:
從http://www.adobe.com/go/flex3_cs3_swfkit下載Flex Component Kit for Flash CS3。
從http://www.adobe.com/go/flex3_skinning下載Flex Skin Design Extensions for Flash CS3.安裝后重啟Flash CS3.
到http://livedocs.adobe.com/flex/3/skinning_extensions_flex3.pdf下載操作手冊。
從上面地址中還可以看到有For Fireworks,For Photoshop等FLEX皮膚制作插件,我們可能在后續文章中介紹實現方法。
首先打開Flash CS3,CTRL+N新建文件,切換“新建文檔”到“模板”面板,選擇Flex Skins->Button,如下圖:
將文件命名為skintemplate.fla,背景色調整#333333。
新建成功后,可以看到舞臺上的按鈕元件。雙擊按鈕元件進入編輯狀態,或者在庫中雙擊Button_skin元件。可看到如下圖所示的時間軸:
簡略的介紹一下這些層的用途。
States:定義對應組件的每種狀態時間線上的關鍵幀,如上圖所示中的關鍵幀幀名
Transitions:定義組件狀態切換時的過渡動畫,默認為每種狀態的最后兩個關鍵幀為起始幀和終止幀,以up狀態切換到over狀態舉例,Transitions層的up-over:start幀為起始幀,up-over:end幀為終止幀,可在art層中制作相應的過渡動畫
Art:組件的圖形部分
你會發現程序只生成了4種狀態,通過前面的學習知道Button組件可以有8種狀態,沒關系,我們在disabled后面再加入4個狀態(注意區分大小寫):
以selectedUp狀態為例:
States層關鍵幀名為selectedUp.
Transitions層,在最后兩幀增加down-selectedOver:start, down-selectedOver:start兩個關鍵幀作為過渡動畫的起始與終止幀.
將前面制作的skin.fla中的Button組件皮膚移植過來。
例如up狀態的:
所有狀態完成后,CTRL+ENTER發布程序,這時會生成skintemplate.swf和skintemplate.swc兩個文件。
然后我們切換到FLEX Builder 3,打開style.css,為了測試新的皮膚,我們要將之前的8種皮膚嵌入語句全部注釋掉。切換到Design面板,注意右邊屬性面板中的Skin屬性:
選擇”Flash symbols…”
加入剛才生成的 skintemplate.swc的路徑,選擇Button_skin元件,點擊OK
左側預覽區已經自動刷新成最新制作的皮膚了:
其實前兩種方法原理類似,只是實現過程有些區別。
嵌入Image文件
除了選取SWF文件的元件嵌入皮膚資源外,還可以選擇Image作為嵌入資源。
首先制作所需Image,以Button組件的Up狀態為例,這里使用Fireworks CS3制作了buttonUp.png,制作過程與方法1相似,這里不再復述,得到圖片如下圖所示:
接下來進入Flex Builder 3,打開style.css,刪除前兩例中的皮膚嵌入代碼。
然后在右側面板中選擇”Image files…”
在彈出的對話框中將Up狀態的Image地址填入我們剛才制作的buttonUp.png。
OK之后左側preview區可以看到Up狀態已經更新了,但是還有重要的一步未做。
我們再點擊右上角的“Edit Scale Grid”,編輯9切片數值。
調整四條虛線到合適位置:
完成后再次點擊“Edit Scale Grid”
切換到Source面板,可以看到自動生成的代碼:
upSkin: Embed(source=”buttonUp.png”,scaleGridLeft=”3″,scaleGridTop=”3″,scaleGridRight=”61″,scaleGridBottom=”20″);
熟練后,可以直接寫代碼而不用手動設置了。
由于時間和篇幅限制,這里只完成Up狀態皮膚了,其他狀態的皮膚可由您來完成。
ActionScript皮膚編程
通過前面三種方法,估計你已經對整個皮膚制作過程有了大概的了解,如果要制作較高級皮膚就得借助ActionScript來實現了。
先來看看CSS中的例句:
upSkin:ClassReference(“UpSkinClass”);
其中UpSkinClass就是我們要實現的皮膚類。
打開Flex Builder 3,在src文件夾下新建skins文件夾,并在skins文件夾下新建類文件:ButtonSkin.as,如下圖所示:
我們選擇mx.skins.Border作為superclass。
為什么要選擇Border類呢?我們先來了解一下幾個可以用于皮膚編程的superclass。
ProgrammaticSkin:實現了IFlexDisplayObject,ILayoutManagerClient,IInvalidating,ISimpleStyleClient接口,是最為容易和通用的superclass。
Border: ProgrammaticSkin的子類,并且加入了borderMetrics屬性,如果皮膚有border屬性可以使用這個類。
RectangularBorder:Border的子類,支持backgroundImage樣式。
UIComponent:實現了IStateCleint接口,易于制作多狀態的組件皮膚,也是實現MXML皮膚時所需的組件。
以上四個類的詳細介紹可參考官方文檔。
好了,我們再回到程序中,通過重寫Border類的updateDisplayList方法來實現皮膚的重繪:
override protected function updateDisplayList(w:Number, h:Number):void
{
//Draw your Graphics.
}
填充以下代碼:
override protected function updateDisplayList(w:Number, h:Number):void
{
var g:Graphics = graphics;
g.clear();
//draw outside border
g.lineStyle(1, 0xFFFFFF, 0.1);
g.drawRect(0, 0, w, h);
//draw
g.lineStyle(1, 0×000000, 0.6);
var gradientBoxMatrix:Matrix = new Matrix();
gradientBoxMatrix.createGradientBox(w, h, Math.PI/2, 0, 0);
g.beginGradientFill(GradientType.LINEAR,[0xFFFFFF, 0xFFFFFF],[0.1,0.0],null,gradientBoxMatrix);
g.drawRect(1, 1, w-2, h-2);
g.endFill();
g.lineGradientStyle(GradientType.LINEAR,[0xFFFFFF, 0xFFFFFF],[0.08,0.03],null,gradientBoxMatrix);
g.drawRect(2, 2, w-4, h-4);
}
保存后打開style.css文件,切換到Source面板,在Button組件樣式下加入代碼:
upSkin: ClassReference(”skins.ButtonSkin”);
注意類包名要寫全。
再切換到Design面板,單擊刷新按鈕
我們的程序已經起作用了:
那么其他狀態呢,每個狀態都要寫一個類嗎?No!
還有一個重要的屬性沒有使用:name
這個name就是狀態實例名稱,例如”upSkin”,”overSkin”等。
用switch語句來判斷不同的實例名稱并進行不同的繪制:
override protected function updateDisplayList(w:Number, h:Number):void
{
var g:Graphics = graphics;
g.clear();
var gradientBoxMatrix:Matrix = new Matrix();
switch(name)
{
case “upSkin”:
{
//draw external border
g.lineStyle(1, 0xFFFFFF, 0.1);
g.drawRect(0, 0, w, h);
//draw inner border and fill in gradual color
g.lineStyle(1, 0×000000, 0.6);
gradientBoxMatrix.createGradientBox(w, h, Math.PI/2, 0, 0);
g.beginGradientFill(GradientType.LINEAR,[0xFFFFFF, 0xFFFFFF],[0.1,0.0],null,gradientBoxMatrix);
g.drawRect(1, 1, w-2, h-2);
g.endFill();
//draw inner high-light border
g.lineGradientStyle(GradientType.LINEAR,[0xFFFFFF, 0xFFFFFF],[0.08,0.03],null,gradientBoxMatrix);
g.drawRect(2, 2, w-4, h-4);
break;
}
case “overSkin”:
{
g.lineStyle(1, 0xFFFFFF, 0.1);
g.drawRect(0, 0, w, h);
g.lineStyle(1, 0×000000, 0.6);
gradientBoxMatrix.createGradientBox(w, h, Math.PI/2, 0, 0);
g.beginGradientFill(GradientType.LINEAR,[0xFFFFFF, 0xFFFFFF],[0.15,0.05],null,gradientBoxMatrix);
g.drawRect(1, 1, w-2, h-2);
g.endFill();
g.lineGradientStyle(GradientType.LINEAR,[0xFFFFFF, 0xFFFFFF],[0.08,0.03],null,gradientBoxMatrix);
g.drawRect(2, 2, w-4, h-4);
break;
}
case “downSkin”:
{
break;
}
case “disabledSkin”:
{
break;
}
case “selectedUpSkin”:
{
break;
}
case “selectedOverSkin”:
{
break;
}
case “selectedDownSkin”:
{
break;
}
case “selectedDisabledSkin”:
{
break;
}
}
}
上示代碼只繪制了upSkin和overSkin兩個狀態的皮膚,其他的皮膚您可以嘗試著完成。
如果覺得在樣式表中每個狀態的皮膚類都要指明很麻煩,可以使用以下語句:
skin: Embed(skinClass=’skins.ButtonSkin’);
或:
skin: ClassReference(”skins.ButtonSkin”);
最后效果如下:
(注:其他樣式因為沒有實現,所以只顯示了Label)
MXML皮膚編程:
此外,我們還可以使用MXML文件來制作皮膚。仍以Button組件制作為例。
打開Flex Builder 3,在FlexSkinTest項目中新建文件夾components,在components文件夾下新建文件夾skins,skins文件夾下新建ButtonSkin.mxml文件:
重寫updateDisplayList方法,并填充上個例子中的繪圖語句。
//fill in the inner array: alpha
private var _innerFrameAlphas:Array = [0.1,0.0];
//inner high-light alpha
private var _innerHighlightAlphas:Array = [0.08,0.03];
override protected function updateDisplayList(w:Number, h:Number):void
{
var g:Graphics = graphics;
g.clear();
var gradientBoxMatrix:Matrix = new Matrix();
g.lineStyle(1, 0xFFFFFF, 0.1);
g.drawRect(0, 0, w, h);
// draw inner border and fill in gradual color
g.lineStyle(1, 0×000000, 0.6);
gradientBoxMatrix.createGradientBox(w, h, Math.PI/2, 0, 0);
g.beginGradientFill(GradientType.LINEAR,[0xFFFFFF, 0xFFFFFF],_innerFrameAlphas,null,gradientBoxMatrix);
g.drawRect(1, 1, w-2, h-2);
g.endFill();
//draw inner high-light border
g.lineGradientStyle(GradientType.LINEAR,[0xFFFFFF, 0xFFFFFF],_innerHighlightAlphas,null,gradientBoxMatrix);
g.drawRect(2, 2, w-4, h-4);
}
再打開style.css,更改嵌入語句:
skin: ClassReference(”components.skins.ButtonSkin”);
此時可以發現皮膚已經更新了:
但是所有皮膚都是相同的,接下來我們設置不同的屬性值區分不同的狀態皮膚。
這時就用到了invalidateDisplayList方法,這個方法會呼叫updateDisplayList方法更新組件。
我們把前面的兩個變量_innerFrameAlphas和innerHighlightAlphas封裝:
public function get innerFrameAlphas():Array
{
return _innerFrameAlphas;
}
public function get innerHighlightAlphas():Array
{
return _innerHighlightAlphas;
}
public function set innerFrameAlphas(alphas:Array):void
{
_innerFrameAlphas = alphas;
invalidateDisplayList();
}
public function set innerHighlightAlphas(alphas:Array):void
{
_innerHighlightAlphas = alphas;
invalidateDisplayList();
}
之后在over這個State中,設置innerFrameAlphas和innerHighlightAlphas屬性,重繪組件。
<mx:State name=”over”>
<mx:SetProperty target=”{this}” name=”innerFrameAlphas” value=”{[0.15,0.05]}”/>
<mx:SetProperty target=”{this}” name=”innerHighlightAlphas” value=”{[0.08,0.03]}”/>
</mx:State>
現在我們再發布一下,你會發現over狀態的皮膚已經更新了。其余狀態的皮膚您可嘗試著完成,這里就不復述了。
最后,如果要在運行時加載皮膚,應把皮膚單獨編譯為SWF文件。
在CSS文件上右鍵->Comile CSS to SWF即可。
也可通過命令行“mxmlc style.css”來編譯。
OK,在FLEX皮膚制作過程中,這幾種方法是比較常用的,靈活運用可以使你的程序增色不少。
總結
- 上一篇: 历年计算机一级b考试试题及答案,全国计算
- 下一篇: OLEDB数据源