页面跳转(Router、Ability)
页面跳转可以分为页面内跳转和页面间跳转,页面内跳转是指所跳转的页面在同一个 Ability 内部,它们之间的跳转可以使用 Router 或者 Navigator 的方式;页面间跳转是指所跳转的页面属与不同的 Ability ,这种跳转需要借助 featureAbility 实现,跳转示意图如下所示:
本节将简单介绍这两种方式的页面跳转。
页面内跳转
页面内跳转的实现比较简单,直接使用 ArkUI 开发框架提供的 Router 或者 Navigator 就可以了, Navigator 本质上是对 Router 的封装,这里就简单介绍一下 Router 的使用,想了解 Navigator 的小伙伴请参考官网文档。
router 定义介绍
declare namespace router {
function pushUrl(options: RouterOptions):void;
function replaceUrl(options: RouterOptions):void;
function back(options?: RouterOptions ):void;
function clear():void;
function getLength():string;
function getState():RouterState;
function enableAlertBeforeBackPage(options: EnableAlertOptions):void;
function disableAlertBeforeBackPage():void;
function getParams(): Object;
}
- pushUrl:打开新的页面,新页面在栈顶位置, RouterOptions 定义了以下参数:
url:目标页面的路径,该路径必须在 config.json 的 pages 下配置,否则不起作用。
params:可选参数,向目标页面传递参数。
replaceUrl:新页面替换当前页面并把当前页面销毁。
back:返回上一页。
clear:清空路由栈里的其它页面。
getLength:获取当前路由栈里的页面数量。
getState:获取当前页面的状态, RouterState 参数说明如下:
- index:当前页面是第几个打开的。
- path:当前页面的路径。
- name:当前页面的名称。
enableAlertBeforeBackPage:
disableAlertBeforeBackPage:
getParams:获取通过路由传递过来的参数。
页面路由
页面路由是指在不同页面之间的跳转和数据传递
页面栈
在鸿蒙中页面栈指的是存储打开的页面。这样方便用户在页面之间进行跳转和数据传递。
页面栈的最大容量上限为 32
个页面
- 清空页面栈,释放内存
router.clear();
Router 有两种页面跳转模式
router.pushUrl()
目标页不会替代当前页,而是压入页面栈,因此可以用 router.back()返回当前页
router.replaceUrl()
目标页会替代当前页,当前页会被销毁并释放资源,无法返回当前页
Router 有两种页面实例模式
Standard
标准实例模式,每次跳转都会新建一个目标页并压入栈顶.默认就是这种模式
Single
单实例模式,如果目标页已经在栈中,则离栈顶最近的同 Url 页面会被移动到栈顶并重新加载
实例
步骤
- 首先要导入 HS 提供的 Router 模块:
import router from '@ohos.router';
- 然后利用 router 实现跳转,返回等操作
router.pushUrl(
{
url:'pages/xxx/xxx',
params:{ id:xxx} // 参数
},
router.RouterMode.Single,
err=>{
if(err){
console.log('路由失败')
}
}
)
参数说明
- RouterOptions
url : 目标页面路径
params:传递的参数(可选)
- 页面模式: RouterMode 枚举
Standard: 标准模式
Single: 单实例模式
- 异常响应回调函数,错误码:
错误码 | 介绍 |
---|---|
100001 | 内部错误,可能是渲染失败 |
100002 | 路由地址错误 |
100003 | 路由栈中页面超过 32 |
获取传递过来的参数
params:any = router.getParams()
返回上一页
router.back()
- 返回指定页面,并携带参数
router.back({id:xxx})
INFO
页面路由跳转的问题。
使用 back()是返回原先页面,并不会在原来页面更新你后来改变的数据
或者是你需要退出重新进入。
所以要想回退,并且改变原先页面的数据请用 replaceUrl()
router.replaceUrl({
url:"xxxxx/xxxx" //路径
})
点击 back 前操作
- showAlertBeforeBackPage 弹出框
router.showAlertBeforeBackPage({
message:"支付好没有完成,确定要返回吗?"
})
router.back()
自定义询问框
在使用页面路由 Router 相关功能之前,需要在代码中先导入 Router 模块。
import router from '@ohos.router';
- 调用弹窗的方法
function onBackClick() {
// 弹出自定义的询问框
promptAction.showDialog({
message: '您还没有完成支付,确定要返回吗?',
buttons: [
{
text: '取消',
color: '#FF0000'
},
{
text: '确认',
color: '#0099FF'
}
]
}).then((result) => {
if (result.index === 0) {
// 用户点击了“取消”按钮
console.info('User canceled the operation.');
} else if (result.index === 1) {
// 用户点击了“确认”按钮
console.info('User confirmed the operation.');
// 调用router.back()方法,返回上一个页面
router.back();
}
}).catch((err) => {
console.error(`Invoke showDialog failed, code is ${err.code}, message is ${err.message}`);
})
}
注意事项
路由页面跳转的路径必须在这个文件里面。否则跳转不过去
页面间跳转
页面间跳转需要借助 featureAbility 模块的 startAbility() 方法,该方法和 router 的功能类似,可以支持参数传递以及打开指定页面等。
featureAbility 定义介绍
declare namespace featureAbility {
/**省略部分方法*/
function startAbility(parameter: StartAbilityParameter, callback: AsyncCallback<number>): void;
function startAbility(parameter: StartAbilityParameter): Promise<number>;
function startAbilityForResult(parameter: StartAbilityParameter, callback: AsyncCallback<AbilityResult>): void;
function startAbilityForResult(parameter: StartAbilityParameter): Promise<AbilityResult>;
}
- startAbility:
打开指定 Ability ,在不指定开目标 Ability 里的页面时,则默认打开 Ability 的第一个页面。
- parameter:设置打开 Ability 的参数,说明如下: (i) want:打开目标 Ability 的配置项。 bundleName:目标 Ability 的包名称。 abilityName:目标 Ability 的全路径。 params:传递给目标 Ability 的参数。可以在该参数里指定需要打开的页面。
打开 Ability 的默认首页面
- 创建第二个 Ability ,依次点击 File -> new -> Ablity -> Empty Page Ability(eTS) ,添加 SettingAbility ,如下图所示:
点击 Finish 后, OpenHarmony 代码结构如下图所示:
- 在 default 的 pages 下的 index.ets 添加跳转功能:引入 featureAbility 模块,然后通过 featureAbility 的 startAbility() 方法打开目标 Ability。
// 引入featureAbility
import featureAbility from '@ohos.ability.featureAbility';
@Entry @Component struct Index {
build() {
Column() {
Button('open about ability')
.onClick(() => {
// 打开目标Ability
featureAbility.startAbility({
want: {
// 目标Ability所在的bundleName,也就是config.json里配置的bundleName
bundleName: "com.example.myapplication",
// 目标Ability的全路径
abilityName: "com.example.myapplication.SettingAbility"
}
})
.then((data) => {
console.info('Operation successful. Data: ' + JSON.stringify(data))
})
.catch((error) => {
console.error('Operation failed. Cause: ' + JSON.stringify(error));
})
})
}
.padding(10)
.width('100%')
.height('100%')
}
}
- 修改 SettingAbility 的默认首页面,添加如下文案:
@Entry @Component struct Index {
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Text('我是SettingAbility的默认首页面')
.fontSize(50)
.fontWeight(FontWeight.Bold)
}
.width('100%')
.height('100%')
}
}
运行结果如下图所示:
打开 Ability 的指定页面
- 在 SettingAbility 的 pages 下添加第二个页面:second.ets,代码如下所示:
@Entry @Component struct Second {
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Text('你好,我是SettingAbility的第二个页面')
.fontSize(50)
.fontWeight(FontWeight.Bold)
}
.width('100%')
.height('100%')
}
}
- 修改打开 Ability 的代码,添加 url 参数,代码如下:
featureAbility.startAbility({
want: {
bundleName: "com.example.myapplication",
abilityName: "com.example.myapplication.SettingAbility",
// 添加uri参数,指定打开SettingAbility下的second页面。
uri: "pages/second"
}
})
.then((data) => {
console.info('Operation successful. Data: ' + JSON.stringify(data))
})
.catch((error) => {
console.error('Operation failed. Cause: ' + JSON.stringify(error));
})
运行结果如下所示: