HDC調(diào)試需求開發(fā)(15萬(wàn)預(yù)算),能者速來(lái)!>>>
簡(jiǎn)介: Flex 是現(xiàn)今最受歡迎的 RIA 開發(fā)技術(shù)之一,它憑借其優(yōu)秀的用戶體驗(yàn)獲得許多用戶的青睞,因此也吸引了眾多的程序員投入 Flex 學(xué)習(xí)的洪流之中。Flex 之所以如此受歡迎,一大部分原因是因?yàn)?Flex 的界面效果非常出眾。Flex 提供了自定義組件外觀的眾多方法,使得 Flex 程序界面豐富多彩。本文通過簡(jiǎn)單實(shí)用的程序例子(包括冒泡信息提示框、圖像圓角、動(dòng)態(tài)按鈕、網(wǎng)格背景),使用位圖、矢量圖、SWF 文件自定義皮膚,使用 Mask 制作遮掩效果,講解了其中幾種自定義組件外觀方法的優(yōu)缺點(diǎn)。通過本文,讀者可以比較系統(tǒng)的學(xué)習(xí)組件自定義外觀的方法,在設(shè)計(jì) Flex 的 UI 時(shí),相信本文可以為讀者提供幫助 .
引言
優(yōu)秀的 Flex 應(yīng)用程序總是絢麗多彩,有些甚至令人瞠目結(jié)舌,不得不稱贊 Flex 的 UI 效果。Flex 組件的默認(rèn)效果一般,那么那些華麗的界面又是如何開發(fā)的呢,這就得靠程序員自定義組件外觀實(shí)現(xiàn)了,Flex 組件提供了許多讓程序員自定義外觀的方式方法,本文通過具體的應(yīng)用實(shí)例,講解其中幾種筆者使用過的自定義組件的方法,相信初識(shí) Flex 的讀者可以從中獲益。
實(shí)例實(shí)現(xiàn)
目前 Flex 已經(jīng)出了 Flex 4 版本,本文使用的是 Flex 3 版本,實(shí)現(xiàn)部分按照下面的列表依次講述。 開發(fā)環(huán)境配置 動(dòng)態(tài)按鈕位圖實(shí)現(xiàn) 動(dòng)態(tài)按鈕 SWF 實(shí)現(xiàn) 冒泡信息提示框 網(wǎng)格背景 圖像圓角
實(shí)際上各個(gè)部分之間沒有明顯的關(guān)系,除了開發(fā)環(huán)境配置,其他每個(gè)部分分別講述了一種自定義組件外觀的方法,因此,讀者可以根據(jù)需要查看具體 部分。附件是標(biāo)準(zhǔn)的 Flex Builder 3 的項(xiàng)目,讀者可以下載后導(dǎo)入,除了開發(fā)環(huán)境配置外,上述列表的其他各個(gè)部分都對(duì)應(yīng)著一個(gè) mxml 文件,可以直接運(yùn)行查看效果。具體對(duì)應(yīng)關(guān)系可以查看附件中的清單。
開發(fā)環(huán)境配置
所有的例子都是使用 Flex Builder 開發(fā),需要 JDK5.0 以上的支持,例子中不需要服務(wù)器的支持,需要安裝 Flash Player 9.0 。
動(dòng)態(tài)按鈕
動(dòng)態(tài)按鈕的的概念就是在鼠標(biāo)懸停、鼠標(biāo)點(diǎn)擊、鼠標(biāo)離開控件時(shí),組件呈現(xiàn)不同的外觀,這三種不同的外觀可以通過背景位圖圖片,背景 SWF 文件實(shí)現(xiàn)。
位圖實(shí)現(xiàn)
位圖實(shí)現(xiàn)是將二進(jìn)制圖像文件作為控件背景,這里使用 Flex 的 Button 控件作為例子,通過定義 Button 的 upSkin、overSkin 以及 downSkin 樣式分別設(shè)置鼠標(biāo)離開 Button 時(shí)、鼠標(biāo)懸停 Button 上方時(shí)以及鼠標(biāo)點(diǎn)擊 Button 時(shí)的皮膚,皮膚制作則使用 Embed 標(biāo)簽加載圖片,使之成為 Class 對(duì)象,通過 Button 的 setStyle 方法將 Class 對(duì)象作為皮膚設(shè)置進(jìn)去,清單 1 展示了其中設(shè)置 upSkin 的方法 .downSkin 和 overSkin 的設(shè)置方法相同。
清單 1. Button 控件設(shè)置 upSkin
var btn:Button= … ; [Embed(source="images/up.jpg", scaleGridTop="26", scaleGridBottom="64", scaleGridLeft="30", scaleGridRight="106")] private var upSkin:Class; btn.setStyle("upSkin",upSkin); |
---|
清單 1 中,Embed 標(biāo)簽內(nèi)的 scaleGridTop、scaleGridBottom、scaleGridLeft、scaleGridRight 屬性涉及到一種 Web 技術(shù),名為九宮格的縮放技術(shù),為了解釋該技術(shù),請(qǐng)先看圖 1.
圖 1. 九宮格原理圖
注:原圖是 ,5 * 5 方格圖,每個(gè)方格 4 個(gè)像素,上圖是被放大后的效果
圖 1 在四條紅線的位置把圖片塊成了 9 塊,四個(gè)角,四條邊和中間一塊,在縮放的時(shí)候,四個(gè)角始終不變,兩條橫向邊只縮放寬度,高度不變,兩條縱向的邊只縮放高度,寬度不變,中間一塊寬和高同時(shí) 縮放,這就是九宮格縮放的原理。這種技術(shù)一般是在使用圖片做控件的皮膚時(shí)使用,很多控件的皮膚樣式,在四個(gè)角的為位置是圓的或不規(guī)則的,所以使用這種縮放 技術(shù)可以保證控件與圖片的大小不一致的時(shí)候,圖片看起來(lái)并不變形。
了解了九宮格技術(shù)再看 scaleGridTop、scaleGridBottom、scaleGridLeft、scaleGridRight 四個(gè)屬性,它們分別代表圖 1 中四條紅色切割線的位置,scaleGridTop 代表橫向頂部的切割線距離圖像頂部的像素距離;scaleGridBottom 代表橫向底部的切割線距離圖像頂部的像素距離;scaleGridLeft 代表縱向左部的切割線距離圖像左部的像素距離;scaleGridRight 代表縱向右部的切割線距離圖像左部的像素距離。
通過上述技術(shù)和方法的使用,具體實(shí)例效果展示如圖 2. 從左至右分別是 upSkin、downSkin、overSkin 的效果。
圖 2. 位圖實(shí)現(xiàn)效果展示圖
SWF 文件實(shí)現(xiàn)
SWF 文件實(shí)現(xiàn)就是用 SWF 文件中具體的某一幀(MoiveClip)作為控件皮膚,修改 位圖實(shí)現(xiàn) 部分的 Embed 標(biāo)簽,構(gòu)建的新的示例,如清單 2.
清單 2. 使用 SWF 具體某幀作為皮膚
Button{ up-skin:Embed(source="images/bg.swf",symbol="btnUP"); over-skin:Embed(source="images/bg.swf",symbol="btnOVER"); down-skin:Embed(source="images/bg.swf",symbol="btnDOWN"); } |
---|
上面代碼 Embed 中的 source 指向了一個(gè) SWF 文件,沒有與九宮格相關(guān)的布局屬性,出現(xiàn)了新的屬性:symbol,它是 SWF 文件中某一幀的標(biāo)識(shí)符,意思是使用指定的幀作為皮膚。清單 2 的效果如圖 3. 從左至右分別是 upSkin、downSkin、overSkin 的效果。
圖 3. SWF 實(shí)現(xiàn)效果展示圖
這種特殊的 SWF 文件需要用到 Flash 開發(fā)工具,具體的開發(fā)方法讀者可以查閱相關(guān)的 Flash 資料。
冒泡信息提示框
冒泡信息提示框是自定義的 ToolTip,傳統(tǒng)的 Flex ToolTip 效果如圖 4 所示。
圖 4. 傳統(tǒng) ToolTip
可以看到效果還是比較簡(jiǎn)陋的,為了增強(qiáng)用戶體驗(yàn),文章實(shí)現(xiàn)了新的 ToolTip 讓其擁有冒泡效果,效果展示如圖 5.
圖 5. 冒泡 ToolTip
冒泡 ToolTip 的思想是新建名為 BubbleToolTip 的類,繼承于 Canvas,實(shí)現(xiàn) IToolTip 接口,IToolTip 是自定義 ToolTip 必須實(shí)現(xiàn)的接口。重寫 BubbleToolTip 的 updateDisplayList 方法,目的是重新繪畫 BubbleToolTip 的皮膚,皮膚的繪制依賴 BubbleToolTip 內(nèi)部的 Graphics 對(duì)象,通過 this.graphics 語(yǔ)句可以獲得該 Graphics 對(duì)象的引用,調(diào)用 Graphics 對(duì)象的 drawRoundRect 方法繪制冒泡的圓形,提示的具體內(nèi)容則使用子對(duì)象 Canvas 存放。清單 3 是 BubbleToolTip 的 updateDisplayList 方法代碼。
清單 3. BubbleToolTip 的 updateDisplayList 方法
override protected function updateDisplayList( unscaledWidth:Number, unscaledHeight:Number ) : void { super.updateDisplayList( unscaledWidth, unscaledHeight ); |
---|
this.graphics.clear();
this.graphics.beginFill( getStyle('backgroundColor'), 1 );
this.graphics.lineStyle(2, getStyle('borderColor'), 1);
this.graphics.drawRoundRect(0, 35, 6, 6, 24, 24);
this.graphics.endFill();
this.graphics.beginFill( getStyle('backgroundColor'), 1 );
this.graphics.lineStyle(2, getStyle('borderColor'), 1);
this.graphics.drawRoundRect(10, 25, 15, 15, 24, 24);
this.graphics.endFill();
}
清單 3 的作用是繪畫圖 5 中黑色的兩個(gè)圓圈,顯示 Hello 信息的則是使用 Canvas 組件,該 Canvas 是在主 MXML 文件中定義,代碼如清單 4 所示。
清單 4. 使用 BubbleToolTip 的 MXML 文件
xmlns:component="component.*" backgroundGradientAlphas="[1.0, 1.0]" backgroundGradientColors="[#FFFFFF, #FFFFFF]"> import mx.events.ToolTipEvent; import component.BubbleToolTip; |
---|
private function createCustomTip(title:String,event:ToolTipEvent):void {
var bt:BubbleToolTip = new BubbleToolTip();
bt.text=title;
content.text = title;
bt.addChild(ppp);
ppp.visible=true;
event.toolTip = bt;
}
private function positionTip(event:ToolTipEvent):void{
event.toolTip.x=event.currentTarget.x + event.currentTarget.width + 10;
event.toolTip.y=event.currentTarget.y;
}
]]>
label="Hello world" x="60" y="60"
toolTip=" "
toolTipCreate="createCustomTip('Hello World',event)"
toolTipShow="positionTip(event)"
/>
borderColor="#000000" x="35" y="0" borderStyle="solid" borderThickness="2">
清單 4 中定義了存放信息的 Canvas ,id 為 ppp,首先設(shè)置 ppp 的 visible 為 false,不可見,在顯示 ToolTip 的時(shí)候?qū)?ppp 加到 BubbleToolTip 中,并且設(shè)置 ppp 為可見。設(shè)置 event.tooltip 為指定的 BubbleToolTip 對(duì)象。在 createCutomTip 方法中設(shè)置新的 ToolTip,在 positionTip 方法中定義 tooltip 的顯示位置。
為了形象的表現(xiàn)出重寫 updateDisplayList 方法前后的 BubbleToolTip 的對(duì)比, 圖 5 顯示的是重寫后彈出的信息提示框,圖 6 是不重寫 updateDisplayList 的信息提示框,從兩張圖片可以看出重寫后發(fā)生的變化。
圖 6. 不重寫 updateDisplayList 方法的 BubbleToolTip
可以看到子對(duì)象的 Canvas 前后不變,因?yàn)椴]有重寫它的 updateDisplayList,而重寫 BubbleToolTip 的 updateDisplayList 方法后邊框變成了兩個(gè)冒泡。注意 BubbleToolTip 對(duì)象實(shí)際上也是一個(gè) Canvas。
網(wǎng)格背景
網(wǎng)格背景在一些 Flex 流程編輯器中可以看到,畫布的網(wǎng)格背景不僅可以增強(qiáng)用戶體驗(yàn),對(duì)于流程編輯中的流程節(jié)點(diǎn)的對(duì)齊也有很大的幫助。
網(wǎng)格背景的容器使用畫布 Canvas 對(duì)象,使用 CSS 重新定義容器的皮膚。定義新皮膚的 CSS 代碼如清單 5.
清單 5. CSS 定義新皮膚 Canvas { borderSkin: ClassReference("skins.GridSkin"); } |
---|
skins .GridSkin 是一個(gè) Flex 類,繼承于 ProgrammaticSkin,ProgrammaticSkin 類代表編程式的皮膚定義,重寫它的 updateDisplayList 方法可以設(shè)置新的皮膚,這和直接重寫 Canvas 的 updateDisplayList 方法效果上是一致的,本文重在講解新的定義方法,因此使用 CSS 定義。清單 6 顯示網(wǎng)格定義的代碼。
清單 6. ProgrammaticSkin 的 updateDisplayList 實(shí)現(xiàn)代碼 override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void { var g:Graphics = this.graphics; g.clear(); g.beginFill(0x000000, 0); g.drawRect(0, 0, unscaledWidth, unscaledHeight); g.endFill(); g.lineStyle(1, 0x000000, 0.1); var squareSize:Number = 15; var numRows:Number = unscaledHeight / squareSize; var numCols:Number = unscaledWidth / squareSize; for(var row:Number = 0; row< numRows; row++) { g.moveTo(0, row * squareSize); g.lineTo(unscaledWidth, row * squareSize); } for(var col:Number = 0; col< numCols; col++) { g.moveTo(col * squareSize, 0); g.lineTo(col * squareSize, unscaledHeight); } } |
---|
清單 6 中的 unscaledWidth 和 unscaledHeight 代表了 Canvas 畫布實(shí)際的寬和高,畫布內(nèi)的 Graphics 對(duì)象默認(rèn)的繪畫原點(diǎn)是畫布左上角(0,0)點(diǎn)。代碼 drawRect(0, 0, unscaledWidth, unscaledHeight) 用于繪畫整個(gè)畫布的邊框,lineStyle(1, 0x000000, 0.1) 設(shè)置將要畫的線的樣式,黑色、透明度 0.1、粗細(xì) 1,squareSize 定義網(wǎng)格的大小(網(wǎng)格為正方形)。通過 unscaledHeight / squareSize 和 unscaledWidth / squareSize 獲得畫布允許的行數(shù)和列數(shù),moveTo 移動(dòng)繪畫原點(diǎn),lineTo 表示從原點(diǎn)到目標(biāo)點(diǎn)畫線。For 循環(huán)代表每畫一行(列),原點(diǎn)向下(右)移動(dòng) squareSize 的距離,再?gòu)脑c(diǎn)平行畫直線到畫布右邊緣(底邊緣)。那么網(wǎng)格效果就出來(lái)了 . 效果如圖 7 所示 .
圖 7. 網(wǎng)格背景效果
圖像圓角
圖像圓角是 Web2.0 重要的標(biāo)志,如果你用過 CSS 進(jìn)行圓角的開發(fā),那么不管在開發(fā)過程中或者處理瀏覽器兼容問題時(shí)一定會(huì)大喊痛苦。然而在 Flex 中,圖像圓角變的非常簡(jiǎn)單,使用 Mask 技術(shù)就可以輕松得實(shí)現(xiàn)。這種技術(shù)的直觀感覺是將某一控件 A 覆蓋在另一控件 B 之上,而 B 顯示的部分則是被 A 遮蓋的部分。如果 A 具有透明度,那么 B 也會(huì)有透明度。例子代碼如清單 7. 所示。
清單 7. 圖像圓角組件 xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:filters="flash.filters.*" width="100%" height="100%" > |
---|
id="maskCanvas" cornerRadius="15" borderStyle="solid"/>
清單 7 中圖像圓角組件實(shí)際上是一個(gè) Canvas,該組件內(nèi)顯示的是一個(gè) Image(A),該 Image 指定 mask 為 maskCanvas,也就是一個(gè) id 為 maskCanvas 的 Canvas(B),代碼的意思是使用 B 遮蓋 A,那么 B 的樣式?jīng)Q定了 A 顯示的樣式,B 的樣式中重要的是 backgroundColor 和 cornerRadius,backgroundColor 設(shè)置成紅色,并不透明,cornerRadius 設(shè)置 B 的圓角(注意,Image 沒有這個(gè)屬性),那么使用深色的 B 遮蓋 A,A 將顯示被 B 遮蓋的部分,也就是顯示了圖像的圓角,效果如圖 8。
圖 8. 圖像圓角效果
該效果使用的原圖像如圖 9 所示。這是一張方形的圖像。
圖 9. 原圖像
從清單 7 的 Design 視圖可以看出 A 和 B 的遮蓋結(jié)果,效果如圖 10。
圖 10. Design 視圖
原圖像主要內(nèi)容被紅色背景的 Canvas 遮蓋,四個(gè)角沒被遮蓋因此運(yùn)行時(shí)則不被顯示。運(yùn)行后效果就會(huì)如圖 8 所示了。
總結(jié)
本文的目的主要在于讓讀者了解 Flex 自定義組件外觀的方法和技巧,如果讀者有興趣的話,可以做進(jìn)一步的研究,掌握更多設(shè)置外觀的方法,讓 Flex 在你手中更加豐富多彩。由于筆者知識(shí)水平有限,如果有錯(cuò)誤的地方,歡迎聯(lián)系我指正。