2007/10/18 | 【转】AIR制作RSS阅读器!
类别(FLEX_AIR_RIA) | 评论(0) | 阅读(393) | 发表于 08:03
文.劉仲濱
【原文链接】


AIR己進入Beta,今年即將蓄勢待發,本篇我們現在來做一個常見的引導範例,建立一個簡單的RSS讀取器,把Adobe的XML新聞聚合器文章撈回來,讓讀者可以看到最新資料,整個部分只利用Flex技巧就辦到了。

先前準備
1.為方便製作此系統,請先下載最新Flex Builder 3 Beta開發工具,下載網址在:http://www.adobe.com/cfusion/entitlement/index.cfm?e=labs_adobeflexbuilder3

2.因為要用到AIR的Runtime執行環境,所以也請務必安裝好AIR環境檔(大小約9MB),您可以直接到Adobe Lab平台上下載,網址在:http://labs.adobe.com/downloads/air.html

建立AIR專案
Flex Builder 3 Beta的安裝方式與其他軟體沒什麼二樣,為使讀者快速抓到重要,我們就直接開啟Flex Builder 3 Beta工具,點選左上角的File->New->AIR Project,之後出現一個對話框,要你輸入新建的專案名稱,我們先取為「MyRssReader」,Server Type選擇預設的Other/None並按下Next,接下來畫面是要你指定此新專案的檔案存放位置,如,我放在D:\Flex.Studio\ MyRssReader」,最後直接按Finish。(當然你可以直接再往下一步,設定細節,不在本篇介紹範圍)

你會發現到在畫面的左邊產生了二個檔,一個副檔是.mxml,這是AIR的主程式檔(預設名字是建立專案名稱),另外是.xml檔,這是AIR的程式描述檔,可以設定程式圖示、版權、系統名稱等。

AIR程式撰寫
我們先定義一下此RSS系統範例的邏輯,
第一步:目的是為了如何去存取及顯示RSS所抓回來的資料。
第二步:如何呼叫文章裡的某一內容並顯示在HTML頁面。
第三步:最後是設定相關AIR樣式及發佈完成之程式。

確認邏輯沒錯的話,那就好辦事了,我們必須要加一個HTTPService實體元件在這程式上,設定好ID識別,以便知道哪一個RssService名稱,並設定url屬性,也就是URL的值,這樣才能建立抓取RSS的管道。

筆者會建立一個rssHandler private function,來處理從HTTPService元件中的RSS資料內容,並匯入mxrpc.events.ResultEvent事件結果。

特別說明的是,雖然HTTPServices元件裡resultFormat屬性,它可以設定不同資料型態,但最好的方法,我們會將元件設定方式減 輕到最小負荷,也就是說將資料結果存在ArrayCollection上,如此一來記憶體在最小的使用量上,就己足夠在dataProvider給顯示元 件上。

另外,我們要建立變數來存放HTTPService傳回結果,你就一定要importArrayCollection類,以便設定變數的資料型態。 最後只要加上一個按鈕在HTTPService元件後面,讓使用者按下按鈕後就會呼叫HTTPServices,執行Send方法,將RSS資料取回來。 如程式碼1。

程式碼1:

<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection; 
import mx.rpc.events.ResultEvent;
[Bindable] private var rssFeedData:ArrayCollection;
private function rssHandler(event:ResultEvent):void
{
rssFeedData = event.result.RDF.item;
}
]]>
</mx:Script>
<mx:HTTPService id="RssService" url="http://weblogs.macromedia.com/mxna/xml/rss.cfm?query=byMostRecent&languages=1"
result="rssHandler(event)"/>
<mx:Button label="Fetch RSS" click="RssService.send()"/>

AIR因為是啟動視窗畫面關係,所以它可以讓你設定顯示模式,請你打開與專案名稱一樣後面有-app.xml檔,找到rootContent標籤,預設是不會有width(寬度)與高度,所以請你加上自訂的大小,如下。

<rootContent systemChrome="standard" transparent="false" visible="true" width="800" height="600">[SWF reference is generated]</rootContent

systemChrome設定值有standard或none,表示與一般視窗顯示一樣,有標題列、最小化、關閉按鈕等。none則要指名要顯示哪 個視窗控制內容,如列有最小化、關閉按鈕等。transparent 是可以讓你設定視窗要不要透明化,visible是執行時要不要顯示視窗,有如背景執行模式。這裡的寬與高是包含了整個視窗外圍。
資料顯示佈局
在這範例中,我們會用到TitleList元件來顯示撈回來的資料,用其itemRenderer屬性值來支配自訂元件,好處就是可以把每筆資料秀在元件裡。

這有幾個原則要記住,給renderer使用的自訂元件是建立在最外層的Canvas元件裡,設定上會使用絕對值來決定每個元素的排版位置,文字控 制上是允許你自動斷行顯示,技巧上,盡可能使用y的位置設定來動態顯示,如同程式碼2所示。檔名請存成ItemRenderer.mxml在專案根目錄 上。

程式碼2


<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" horizontalScrollPolicy="off" verticalScrollPolicy="off">
<mx:DateFormatter id="dateFormatter" formatString="D-MMM-YY"/>
<mx:Text id="Title"
htmlText="{data.title}"
x="5" y="0"
fontSize="11" selectable="false"
width="780"
textAlign="left" fontWeight="bold"/>
<mx:Text id="PublishDate"
text="{dateFormatter.format(data.date)}"
x="5" y="{Title.height+3}"
fontSize="9" selectable="false"
width="200"
textAlign="left"
fontWeight="bold"/>        
<mx:Text id="Author"
text="{data.creator}"
x="68" y="{Title.height+3}"
fontSize="9" selectable="false"
width="200"
textAlign="left" fontWeight="bold"/>
<mx:LinkButton id="ReadArticle"
label=">請 詳 細 內 容"
x="700" y="{Title.height-3}"
fontSize="12"
rollOverColor="#B8AF9C"
selectionColor="#595341"
textRollOverColor="#FFFFFF"
textSelectedColor="#FFFFFF"/>  
<mx:Text id="Description"
htmlText="{data.description}"
x="5" y="{Title.height+20}"
fontSize="10" selectable="false"
width="780"
textAlign="left"/>
<mx:HRule x="0" y="115" width="100%"/>
</mx:Canvas>

緊接著,就是要建立邏輯程序來呼叫及顯示在TileList裡點文章的HTML頁面,使用TabNavigator(標籤導覽器)在程式裡是個不錯的選擇,很快地就可以切換你點選的RSS文章內容。

像是HTML語言一樣,我們先把VBox容器以巢狀方式建立在TbNavigator裡,而ProgressBar元件也是加入在VBox中,以告訴使用者現在RSS是正在抓取資料的狀況。

有些情況下,若你不想把ProgressBar顯示出來,而在程式上又必須要加上時,你可以把它的高度設為0,這樣就可以直接隱藏起。在Flex裡的排版後如同圖1所示。

元件在Flex設計工作區排版後的樣式
圖1:元件在Flex設計工作區排版後的樣式

在此程式範例裡,我們也需要加個文字按鈕,把RSS讀進來的內容,讓任何人都可以再去點選該篇文章網址,以便可以看到所有內容。

這也是ArrayCollection迷人的地方,每一個值,事實上都己存放在這物件上,它會依序傳遞給每一個ItemRenderer實體資料, 也因此,你早就可以將ItemRenderer裡的資料顯示在TileList元件裡。而且在TileList元件中的每一個Item都是己做好虛擬化的 介面,如滑鼠移到文字按鈕或點選時,都會有不同變化。

好,我們再這裡的點選事件上就必須要處理,通常是在這支程式上來寫捕足的事件,或者是直接寫在ItemRenderer檔裡。這樣才會滿足抓到適當的URL。

而加上EventListener到TileList是要讓你不管在哪一筆的資料下,只要是click按觸發了,就會指定負責的事件要與方法來處理這問題。你不能用參數來傳遞額外的內容,必須用其method(方式)來執行。

像這樣的作法在AS3很常見,就是建立一個自訂的事件類別來處理,加到這連結按鈕在ItemRenderer中。

建立自訂事件很簡單,我們先在專案根目錄上建立一個events的資料夾,這裡都會放所有的事件類別,類別裡需要包含屬性,才能讓你在這自訂事件上一併傳出去。

好,我們加上屬性在這類別中,取名為article,型別為Object。接著再針對此類別建一個constructor,目的是要帶2個參數;第 一個型態也是Object,第二則為String。這constructor需要呼叫super類別來傳遞型別與參數,才能允許做bubbling的功能 (此後續文章再談)。放在此自訂事件的屬性參數我們會使用this文字前面,如程式碼3,檔名取為 ReadArticleCustomClass.as:。

程式碼3

package events
{
import flash.events.Event;
public class ReadArticleCustomClass extends Event
{
public var article:Object;
public function ReadArticleCustomClass(articleParam:Object,type:String)
{
super(type,true);
this.article = articleParam;
}
override public function clone():Event
{
return new ReadArticleCustomClass(article,type);
}
}
}

自訂事件類別也需要宣告在ItemRenderer.mxml裡,才能派上用場。你只要在MetaData標籤加上2個參數就可以了,一個是name(名稱),另一個是type表示放在哪個相對位置。如下所示。

<mx:Metadata>
[Event(name="readArticle",type="events.ReadArticleCustomClass")]
</mx:Metadata>
現在就再連結按鈕加上handler表示要如何派送執行自訂事件即可。
請利用Script的區塊加在Metadata後面,並且匯入自訂事件類別,在這Script區塊裡輸入Private方法以便被文字按鈕呼叫後去建立自訂事件類別實體。如程式碼4,可別忘了你也要加上function call在文字按鈕上來觸發。

程式碼4

<mx:Script>
<![CDATA[
import events.ReadArticleCustomClass;
private function readArticleHandler():void
{
var eventObj:ReadArticleCustomClass = new ReadArticleCustomClass(data,"readArticle");
dispatchEvent(eventObj);
}
]]>
</mx:Script>

現在切換到原來的MyRssReader.mxml主程式檔,在這裡匯入剛所立的ReadArticleCustomClass自訂物件,並建立名 為initApp的private function,此函數並不需參數與資型別,這主要用意是程式在初始化時會去從item renderer的自訂事件中抓資料回來。

再來,建立一個showArticle()的方法,讓它能夠接收一個事件參數是我們前面建立的ReadArticleCustomClass。範例如程式碼5。

程式碼5

private function initApp():void
{
FeedDisplay.addEventListener("readArticle",showArticle);
}
private function showArticle(event:ReadArticleCustomClass):void
{
currentArticle = event.article.link;
currentArticleLink = event.article["rdf:about"];
ContentNavigator.selectedIndex = 1;
}        
private function rssHandler(event:ResultEvent):void
{
rssFeedData = event.result.RDF.item;
RssLoader.height=0;
}
private function showArticleTab():void
{
if (articleLoader.location != currentArticleLink) articleLoader.location = currentArticle;
articleLoader.loaded?HtmlLoader.height=0:HtmlLoader.height=30;
}

發佈AIR程式
好了,請最後記得存檔,我們現在就可以發佈AIR程式了,你可以直接到專案上按右鍵,再按Export,對話視窗出現後,請選擇Adobe AIR下的Adobe AIR Package,緊接著按Next後的畫面,主要就是Project、Application、Include files與Save as(要存的AIR檔名)要設定,若你本身就是開啟目前的專案,可以直接按下Finish鍵即可。有沒有發現發佈AIR的過程幾乎都幫你設好了?

現在我們看一下此RSS AIR程式執行後的畫面。恭喜你了,你己跨出瀏覽器的第一步。
讀取Adobe RSS新聞範例

圖2:讀取Adobe RSS新聞範例

 

關於AIR有些支援你應該要知道

一、Dreamweaver CS3己支援AIR

別懷疑,你只要下載使用AIR Extension for Dreamweaver CS3就能夠將現有網頁開發技巧帶到桌面環境上使用,並且目前支援Windows與Mac二種平台。
下載網址:http://labs.adobe.com/wiki/index.php/AIR:Dreamweaver_CS3_Extension

二、Flash CS3 For AIR

目前Adobe內部正在開發Flash CS3針對AIR上的廷伸支援,己宣稱下一版一定會有內建AIR,但己等不及的朋友,你可以到http://www.flashguru.co.uk/create-apollo-apps-in-flash-cs3/取得使用方式,當然這也是要你事先有裝上AIR SDK才行。

三、第三方佈署AIR工具-Aptana

除了使用Adobe的Flex Builder來開發AIR程式外,也推薦你可以參考社群常使用的另一個IDE工具-Aptana,Aptana它是一個免費的IDE工具,特性是在 Ajax的開發,支援了HTML、CSS、JavaScript等,同時它有針對AIR提供專屬插件。
下載及更多Aptana資源可以到這裡http://www.aptana.com/air/參考。

四、框架(Frameworks)

Adobe Lab列出推薦的3種JavaScript框架,讓你方便建立AIR應用程式。

  1. Ext JS,前端JavaScript的框架,最新版本是Ext 1.1RC版,你可以直接到http://extjs.com/取得相關資源。
  2. Prototype,主要以類別來驅動,並有豐富的Ajax函式庫,目的是讓開發者容易建立動態網頁,更多資源請到http://www.prototypejs.org/取得。
  3. Script.aculo.us,這也是相當有趣的JavaScript框架,你到http://script.aculo.us/查閱後,你會察覺到與其他動態語言上的整合說明交待得很清楚。

作者簡介:
劉仲濱
國立交通大學電機資訊學院數位圖書組碩士,研究 Adobe/macromedia相關產品多年,為國內企業暨華人社群大力推展 RIA互動多媒體應用暨解決方案,著作有相關Adobe/Macromedia網頁書籍、多篇雜誌專欄,同時為大型研討會講師,某公司技術顧問,及RiS 平台(http://j2eemx.com)資深社群主持人。

1

评论Comments