AppWorker教程-页面跳转

页面跳转

Page是AppWorker应用中最重要的概念,我们详细介绍Page的一下相关问题,相关的App和UI的概念也会介绍,适合所有初学者。

一. 概念

Page是管理一组ui和相关逻辑的基本集合。如果了解Android和iOS的话,Page等同于Android的Activity和iOS的UIViewController。

从视觉上来看,一个Page是一个扩充全屏的一个View,这个View包含一个主ui,主UI又可以包含很多个子ui,这里的ui指一个ui文件。从逻辑上来说,一个Page通常管理业务逻辑的一个模块,比如登陆页面,首页等等,我们平常设计App的时候,每个页面通常就指一个Page。

二. 组织结构

1. Page栈

一个AppWorker的App包含一个do_App对象,包含多个Page(do_Page对象)。通过do_App维护一个栈来管理多个Page对象,如下图。

《AppWorker教程-页面跳转》

管理手段其实就2个方法:openPage和closePage,对应上面的图就是压栈和出栈。这个图表示App运行时当前的页面情况,Page1上面是Page2,Page2上面是Page3,Page6是栈顶,在当前时刻,用户只能看见Page6,因为Page是全屏不透明的。但是其它3个Page还是在应用的内存中,并没有释放。

do_Page是一个SM对象,但是是一个特殊的SM对象,通常一个SM对象在整个App没有退出前,在任何地方都只有一个对象实例,也就是在任何时刻获取这个对象的地址都是一样的。Page对象特殊在于它并不是唯一示例,但是由于用户只能操作Page栈顶的Page,所以不会有什么问题。

//比如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());//任何时刻任何地方执行值都一样

print(album.getAddress());//任何时刻任何地方执行值都一样

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

2. Page交互设计

有一个常见问题就是App的设计思路沿用了浏览器加载网页的思路,不断的openPage而不closePage。正确的页面跳转交互设计应该是树状结构,而不应该是网状结构,如下图:

《AppWorker教程-页面跳转》
《AppWorker教程-页面跳转》

我们来比较一下,从page1到page3再到page8的过程中,Page栈的内容差异如下

正确的方式

page1—>page2

page1—>page2—>page3

page1—>page2

page1

page1—>page8

错误的方式

page1—>page2

page1—>page2—>page3

page1—>page2—>page3—>page8

我们可以看到错误的方式会导致栈一直增加,从不或者很少出栈,经常出现的问题是page1打开page2,page2又打开page1,导致循环,这样很快内存就会耗尽导致app闪退,而且这种方式导致数据的流转非常混乱。

为了避免栈太深,Android限制了最多只能16层。也就是page1打开page2,page2打开page3,一直到page16就无法再openPage了。

三. 生命周期

一个Page的开始是由openPage开始,到结束closePage,它的基本流程是如下图:

《AppWorker教程-页面跳转》

有一些问题需要进一步解释

1. 每个Page都有一个主ui文件,比如当前栈顶是app.js,在app.js里执行openPage代码

//app.js

app.on(“loaded”, function () {

    d1.print(“start open page”);

    app.openPage(“source://view/index.ui”);

});

执行完,那么新的page打开,这个page的主ui就是index.ui。但是index.ui.js里可能会加载一个或多个子ui,通常2种方式引进子ui

//index.ui.js

//第一种:通过add方法在现有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”);

这样当前栈顶的page主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事件里执行。

//index.ui.js

var  page = sm(“do_Page”);

page.on(“loaded”,functioin(){

    //在新的page页面弹出之后,才执行下面的代码

    var layout = ui(“ALayout_1”);

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

})

上面的例子并没有加载1.ui和3.ui 是因为do_ViewShower组件处理过,只有showView的时候才去加载,而addViews的时候不加载,为了提高效率。

这里可以参考完整的例子,执行的时候可以看到在Logger看到加载的顺序打印。

3. Page的生命周期中还有pause和resume事件,平常用的不是很多,请参考API文档.

result事件用的非常多,下面还会详细说

四. 数据传递

涉及到2个部分,page和page之间的数据传递,单个page里的主ui和子ui之间的数据传递

1. Page与Page之间的数据传递

Page1需要在打开Page2的时候去传递一些数据给Page2,Page2关闭自身,需要通知Page1并传递一些数据,这个过程主要依靠openPage,closePage的data参数以及result事件来实现。

这一部分在文档数据分享和数据传递有了详细的介绍

2. 一个Page内数据传递

单个page里的主ui和子ui之间的数据传递主要依靠page对象的自定义消息的机制。一个ui订阅page的一个消息,另外一个ui触发这个消息。这一部分在文档事件机制有了详细的介绍

五. closePage多层

Page栈是通过openPage一层层的压栈,通过closePage一层层的出栈,并不能跳跃的关闭栈内任意Page,但是AppWorker支持一次closePage多层或关闭到某一特定层

二种方式

1. 一次关闭多层

《AppWorker教程-页面跳转》

2. 直接关闭到特定层,其中page1的唯一标示是’pageid1’

《AppWorker教程-页面跳转》

    原文作者:wtcgzh
    原文地址: https://www.jianshu.com/p/f312d6dc669b
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞