歷史背景
在傳統的Flex AIR桌面應用程序開發中,我們有足夠的屏幕分辨率以及系統資源來在屏幕下填充足夠的信息已滿足我們的開發需求。通過采用分層菜單和彈出窗口,我們可以在屏幕上堆砌足夠多的信息。與此相比,智能手機的屏幕感覺像stamp。由於分辨率以及不同設備DPI的影響,Flex mobile開發通常采用Screen Split技術,將頁面切分成很多部分來展示。Flex mobile SDK通過View和ViewNavigator提供了這一默認實現。
Mobile SDK實現
View和ViewNavigator是這個Flex mobile SDK中的新概念,它通過內建機制實現Screen Split,以允許開發人員在他們的應用程序中動態地創建和瀏覽分層次的內容。
默認提供功能
- ViewNavigator導航到任意視圖的能力
- 內存管理機制,支持不同的銷毀策略,使得開發人員可以將視圖保存在內存中
- 提供View transitions的默認實現,還支持自定義transitions過程
- 數據傳遞機制
- 數據持久化機制
- 與移動設備的交互,比如系統的Back按鍵
注:Don’t reinvent the wheel
與View Stack的關系
ViewNavigator與mx:ViewStack容器非常類似,它使得開發人員可以在一個特定的視圖區域中快速地交換內容。 這兩種組件之間最大的差別在於它們各自使用的導航模型。 ViewStack只能在預先定義的狀態間跳轉。 而ViewNavigator的內容管理系統使得開發人員可以動態地激活任意數量的視圖並按照用戶初始使用的順序快速地跳轉回之前的視圖。 這使得ViewNavigator可以自動創建並保留導航歷史,以及更好地展現被大部分移動應用程序所使用的導航模型。 除此之外,ViewNavigator還包含了一個數據模型,這個數據模型使得視圖可以在活動狀態和應用程序會話之間自動保持它們的狀態。
與State的關系
雖然ViewNavigator與View State的使用場景是重合的,但是ViewNavigator不應該被認為是State的替代品,而是一項能夠與State共存的功能。 Views與States是相似的,它們都允許開發人員按要求改變內容,但是它們的使用場景並不是完全匹配的。 State是一個側重於在某種程度上及時地對組件和屬性的一個預先定義的組成部分進行改變的系統,在這個系統中,這些狀態是由一個單一的邏輯線程所管理的。 而從另一方面來說,Views(視圖)支持將所有的邏輯和相關的內容集中到一個單一的組件中,在應用程序執行導航操作時,該組件會被完全替換。 每一個View(視圖)都能夠單獨存在,並且應該包含對應於它所代表的應用程序狀態的特定邏輯。 例如,一個手機通訊錄應用程序包含兩個視圖,一個SearchView(搜索視圖)和一個infoView(信息視圖)。 SearchView(搜索視圖)包含連接到聯系人目錄、搜索聯系人和顯示結果列表的組件和功能。 InfoView(信息視圖)顯示了一個表格,並且只知道如何使用傳遞進來的聯系人數據對象來填充各個顯示字段。 這些視圖能夠相互獨立地存在,請不要共享它們各自功能特有的組件和運行邏輯。 雖然這也可以通過State來實現,但是邏輯可能會更復雜一點。
View and ViewNavigator
ViewNavigator
ViewNavigator 組件是由 View 對象集合組成的容器,其中僅最頂部的視圖可見且處於活動狀態。使用 ViewNavigator 容器控制在手機應用程序的視圖之間的導航。
ViewNavigator可以被分解為兩個主要的組成部分,分別是ActionBar和視圖內容區域。
這張圖片顯示了ViewNavigator的兩個組成部分。
內容區域是包含當前可見視圖的主要分組。 當視圖被創建時,它們會作為子元素被動態地添加到該分組。 ViewNavigator還包含一個集成到它里面的ActionBar組件,用來顯示當前視圖的上下文信息。 通過使用View提供的api,可以將視圖標題之類的屬性或者與視圖相關的動作按鈕放置在這一欄中。 每個viewnavigator中只有一個ActionBar實例,所以這個組件是在所有視圖間共享的。 當一個視圖被激活時,它會更新ActionBar中的內容。
View
View 類是視圖導航器使用的所有視圖的容器基類(官方建議其做為應用程序的所有視圖的基類)。 一個視圖可以被認為是包含一個集成數據模型和附加功能的標准的Flex 4 ItemRenderer,它可以向外部組件(比如ActionBar)提供關於它自己的上下文信息。 一個視圖將會有一個data屬性,這個屬性可以被用來顯示視圖的內容和狀態。 當視圖被激活和取消激活時,視圖的navigator可以自動地對該視圖對象進行序列化、保留狀態和恢復操作。
View Template Properties
視圖將提供一系列可以表達上下文信息的屬性,這些上下文信息可以被外部組件有選擇地顯示。
ActionBar的相關屬性
屬性 | 說明 |
title | 顯示在ActionBar的title區域中的視圖標題 |
titleContent | 應該被顯示在ActionBar的content區域內的UI組件 |
titleLayout | 存放視圖的titleContent的內容分組的布局 |
navigationContent | 應該被顯示在ActionBar的導航內容區域內的UI組件 |
navigationLayout | Actionbar的導航內容分組的布局 |
actionContent | 應該被顯示在ActionBar的動作內容區域內的UI組件 |
actionLayout | 展現動作內容的內容分組的布局 |
以上所有的ActionBar屬性,同樣存在於ViewNavigator中。 這使得navigator可以為這些屬性定義默認值。
ViewNavigator的相關屬性
屬性 | 說明 |
actionBarVisible | 用來指定視圖是否需要Actionbar顯示 |
overlayControls | navigator的Actionbar是否應該懸停在視圖內容區域的上方 |
destructionPolicy | 用於設置一個視圖的銷毀策略 |
視圖管理
ViewNavigator將使用一種基於堆棧的方法來管理視圖。 Navigator會在其內部形成一個視圖對象的載體,稱為一個導航堆棧,其中位於堆棧最頂部的視圖是活動且可見的。 ViewNavigator將提供push和pop操作來供開發人員操作視圖堆棧。
例如,調用navigator.pushView(MyView)會通知navigator創建並添加一個新的視圖到導航堆棧的頂部,然后顯示它。 而調用navigator.popView()會使得navigator銷毀當前視圖,然后重新創建並顯示堆棧中的前一個視圖。 這使得開發人員可以動態地瀏覽他們的應用程序中的內容。
提供的View堆棧管理方法
- navigator.popALL() - remove all view in the stack
- navigator.push(SecondScreen, data, context) – move to a new screen
- navigator.popView() – move back to the previous screen
- navigator.popToFirstView() – jump to the first screen
- navigator.activeView – returns the active view
- navigator.replaceView(SecondScreen, data, context) – replace the top view
注:位於最頂部的視圖總是活動和可見的那個視圖。 ViewNavigator沒有提供一個可以讓開發人員選擇並且顯示導航堆棧中的一個指定視圖的機制。
銷毀策略(Destruction Policies)
ViewNavigator最初的實現方式是在同一時刻僅允許一個視圖為可見。 當一個新的視圖被激活時,前一個視圖的UI組件會被刪除。 這使得Flex應用程序在使用ViewNavigator時可以更好地節省內存空間。 但是在一些情況下,當用戶瀏覽應用程序時,銷毀和重新創建視圖的代價會非常高。 為了處理這種情況,視圖具有一個destructionPolicy屬性,這個屬性決定了當視圖在堆棧中被替換時應該執行什么操作。 默認情況下,這個屬性將會被設置為"auto",這意味着視圖在被移除后應該被立即銷毀。 如果該屬性值被設置為"never",則該視圖將會被保留在內存中。 如果開發人員知道一個視圖要花非常長的時間來進行實例化,或者開發人員不想失去視圖中的內容,這個屬性使用起來會非常有用。
Views life cycle
數據處理
- 使用destructionPolicy屬性處理視圖之間的數據
- View切換,Push操作的數據處理
- View返回,Pop操作的數據處理
- 在應用程序執行之間保存數據
Push操作時的數據處理
- FisrtView調用Push方法
navigator.pushView( SecondView, data );
push方法的context參數也可以利用起來,以完成一些特殊操作
- SecondView監聽FlexEvent.ADD事件
protected function addHandler(event:FlexEvent):void
{
trace(“Do sometings!”);
titleText.text = data.title;
contentText.text = data.content;
}
Pop操作時的數據處理
當一個視圖被從堆棧中彈出時,它將被框架自動銷毀。 在這發生之前,視圖可以選擇返回數據到將要被激活的視圖。 當一個視圖被移除的時候,navigator將保存由視圖的createReturnObject()方法返回的對象,並將其發送到新的視圖中。 默認情況下,這不會返回任何信息。 如果一個視圖想要返回一個自定義對象,開發人員將需要重寫這個方法,以返回一個自定義的對象。 當新的視圖被創建時,它的returnedObject屬性將被設置為這個已保存的對象。 ReturnedObject屬性將被確保在視圖接收FlexEvent.ADD事件之前進行設置。
請注意,只有當使用一種彈出導航操作(例如,popView)將一個視圖從導航堆棧中彈出時,這項功能才是有效的。
- SecondView overide function createReturnObject
override public function createReturnObject():Object
{
//return anyting you want
return xxx;
}
- FirstView監聽FlexEvent.ADD事件
protected function addHandler(event:FlexEvent):void
{
var vo:ViewReturnObject = navigator.poppedViewReturnedObject;
if (vo)
{
//xxx is vo.object
trace(“Do sometings!”);
}
}
注:1、4詳細處理方案見參考文獻中的Adobe教程
PPT:http://files.cnblogs.com/god_bless_you/Flex移動開發.ppt
參考文獻:
- Adobe官方文檔 developing_mobile_apps_flex_4.6.pdf
- View和ViewNavigator——功能與設計規格說明書
- Understanding flex mobile views and viewnavigator
- Flex移動開發技巧--第一部分:數據處理
- Building a mobile employee directory sample with Flex and Flash Builder