AppWorker教程-頁面跳轉(zhuǎn)

頁面跳轉(zhuǎn)

Page是AppWorker應(yīng)用中最重要的概念,我們詳細(xì)介紹Page的一下相關(guān)問題,相關(guān)的App和UI的概念也會介紹,適合所有初學(xué)者。

一. 概念

Page是管理一組ui和相關(guān)邏輯的基本集合。如果了解Android和iOS的話,Page等同于Android的Activity和iOS的UIViewController。

從視覺上來看,一個Page是一個擴充全屏的一個View,這個View包含一個主ui,主UI又可以包含很多個子ui,這里的ui指一個ui文件。從邏輯上來說,一個Page通常管理業(yè)務(wù)邏輯的一個模塊,比如登陸頁面,首頁等等,我們平常設(shè)計App的時候,每個頁面通常就指一個Page。

二. 組織結(jié)構(gòu)

1.?Page棧

一個AppWorker的App包含一個do_App對象,包含多個Page(do_Page對象)。通過do_App維護一個棧來管理多個Page對象,如下圖。

管理手段其實就2個方法:openPage和closePage,對應(yīng)上面的圖就是壓棧和出棧。這個圖表示App運行時當(dāng)前的頁面情況,Page1上面是Page2,Page2上面是Page3,Page6是棧頂,在當(dāng)前時刻,用戶只能看見Page6,因為Page是全屏不透明的。但是其它3個Page還是在應(yīng)用的內(nèi)存中,并沒有釋放。

do_Page是一個SM對象,但是是一個特殊的SM對象,通常一個SM對象在整個App沒有退出前,在任何地方都只有一個對象實例,也就是在任何時刻獲取這個對象的地址都是一樣的。Page對象特殊在于它并不是唯一示例,但是由于用戶只能操作Page棧頂?shù)腜age,所以不會有什么問題。


//比如do_App是一個SM對象,do_Album是一個SM對象,do_Page是一個SM對象

var app = sm("do_App");

var album = sm("do_Album");

var page = sm("do_Page");

print(app.getAddress());//任何時刻任何地方執(zhí)行值都一樣

print(album.getAddress());//任何時刻任何地方執(zhí)行值都一樣

print(page.getAddress());//返回的值可能不一樣


2.?Page交互設(shè)計

有一個常見問題就是App的設(shè)計思路沿用了瀏覽器加載網(wǎng)頁的思路,不斷的openPage而不closePage。正確的頁面跳轉(zhuǎn)交互設(shè)計應(yīng)該是樹狀結(jié)構(gòu),而不應(yīng)該是網(wǎng)狀結(jié)構(gòu),如下圖:

我們來比較一下,從page1到page3再到page8的過程中,Page棧的內(nèi)容差異如下

正確的方式

page1—>page2

page1—>page2—>page3

page1—>page2

page1

page1—>page8

錯誤的方式

page1—>page2

page1—>page2—>page3

page1—>page2—>page3—>page8

我們可以看到錯誤的方式會導(dǎo)致棧一直增加,從不或者很少出棧,經(jīng)常出現(xiàn)的問題是page1打開page2,page2又打開page1,導(dǎo)致循環(huán),這樣很快內(nèi)存就會耗盡導(dǎo)致app閃退,而且這種方式導(dǎo)致數(shù)據(jù)的流轉(zhuǎn)非常混亂。

為了避免棧太深,Android限制了最多只能16層。也就是page1打開page2,page2打開page3,一直到page16就無法再openPage了。

三. 生命周期

一個Page的開始是由openPage開始,到結(jié)束closePage,它的基本流程是如下圖:

有一些問題需要進一步解釋

1.?每個Page都有一個主ui文件,比如當(dāng)前棧頂是app.js,在app.js里執(zhí)行openPage代碼


//app.js

app.on("loaded", function () {

? ? d1.print("start open page");

? ? app.openPage("source://view/index.ui");

});


執(zhí)行完,那么新的page打開,這個page的主ui就是index.ui。但是index.ui.js里可能會加載一個或多個子ui,通常2種方式引進子ui


//index.ui.js

//第一種:通過add方法在現(xiàn)有ui上添加新的ui

var layout = ui("ALayout_1");

layout.add("idtest", "source://view/added.ui")

//第二種:很多容器組件可以添加多個子ui

var viewshower = ui("do_ViewShower_1");

var data = [ {

? ? "id" : "test1",

? ? "path" : "source://view/1.ui"

}, {

? ? "id" : "test2",

? ? "path" : "source://view/2.ui"

}, {

? ? "id" : "test3",

? ? "path" : "source://view/3.ui"

} ];

viewshower.addViews(data);

viewshower.showView("test2");


這樣當(dāng)前棧頂?shù)膒age主ui就是index.ui,里面包含了子ui是 added.ui,1.ui,2.ui,3.ui?

2.?上個例子,added.ui,2.ui都加載完,而且added.ui.js,2.ui.js都加載完,新的page才開始以動畫的形式打開。為了提高效率和體驗,可以把一些子ui以到page打開之后才加載。比如放到page的loaded事件里執(zhí)行。


//index.ui.js

var? page = sm("do_Page");

page.on("loaded",functioin(){

? ? //在新的page頁面彈出之后,才執(zhí)行下面的代碼

? ? var layout = ui("ALayout_1");

? ? layout.add("idtest", "source://view/added.ui")

})


上面的例子并沒有加載1.ui和3.ui 是因為do_ViewShower組件處理過,只有showView的時候才去加載,而addViews的時候不加載,為了提高效率。

這里可以參考完整的例子,執(zhí)行的時候可以看到在Logger看到加載的順序打印。

3.?Page的生命周期中還有pause和resume事件,平常用的不是很多,請參考API文檔.

result事件用的非常多,下面還會詳細(xì)說

四. 數(shù)據(jù)傳遞

涉及到2個部分,page和page之間的數(shù)據(jù)傳遞,單個page里的主ui和子ui之間的數(shù)據(jù)傳遞

1.?Page與Page之間的數(shù)據(jù)傳遞

Page1需要在打開Page2的時候去傳遞一些數(shù)據(jù)給Page2,Page2關(guān)閉自身,需要通知Page1并傳遞一些數(shù)據(jù),這個過程主要依靠openPage,closePage的data參數(shù)以及result事件來實現(xiàn)。

這一部分在文檔數(shù)據(jù)分享和數(shù)據(jù)傳遞有了詳細(xì)的介紹

2.?一個Page內(nèi)數(shù)據(jù)傳遞

單個page里的主ui和子ui之間的數(shù)據(jù)傳遞主要依靠page對象的自定義消息的機制。一個ui訂閱page的一個消息,另外一個ui觸發(fā)這個消息。這一部分在文檔事件機制有了詳細(xì)的介紹

五. closePage多層

Page棧是通過openPage一層層的壓棧,通過closePage一層層的出棧,并不能跳躍的關(guān)閉棧內(nèi)任意Page,但是AppWorker支持一次closePage多層或關(guān)閉到某一特定層

二種方式

1.?一次關(guān)閉多層

2.?直接關(guān)閉到特定層,其中page1的唯一標(biāo)示是’pageid1’

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容