在Java开发模式下,页面跳转和传参
页面间跳转分为Page(Ability)内跳转和Page(Ability)外跳转两种情景,两种情景跳转都需要借助 Intent 来实现,另外传递参数也可以记住 Intent 来携带参数(这点与Android类似)
Page(Ability)内跳转
这种场景就类似于Android应用内的跳转
效果图:

[$]
在同一个Page(Ability)内跳转时,当发起跳转的AbilitySlice和跳转目标的AbilitySlice处于用一个Page时,可以通过 present() 方式进行跳转
Button btn = (Button) findComponentById(ResourceTable.Id_btn); btn.setClickedListener(new Component.ClickedListener() { @Override public void onClick(Component component) { /* 通过 present() 实现 Page (Ability)内跳转 参数一:要跳转的 AbilitySlice 参数二: Intent对象 */ present(new ContentAbilitySlice(),new Intent()); } });
如果在跳转返回时,需要获取其返回结果,则可以使用 presentForResult()实现跳转。用户从跳转目标AbilitySlice返回时,系统将回调 onResult() 来接收和处理返回结果,此时需要重写该方法。返回结果由跳转目标AbilitySlice在其生命周期内通过 setResult() 进行设置。如下代码:
准备跳转的 MainAbilitySlice.java 代码:
package com.example.helloword3.slice; import com.example.helloword3.ResourceTable; import ohos.aafwk.ability.AbilitySlice; import ohos.aafwk.content.Intent; import ohos.aafwk.content.IntentParams; import ohos.agp.components.Button; import ohos.agp.components.Component; import ohos.agp.components.Text; public class MainAbilitySlice extends AbilitySlice { private int REQUEST_CODE = 10; private Text text; @Override public void onStart(Intent intent) { super.onStart(intent); super.setUIContent(ResourceTable.Layout_ability_main); text = (Text) findComponentById(ResourceTable.Id_text); Button btn2 = (Button) findComponentById(ResourceTable.Id_btn2); btn2.setClickedListener(new Component.ClickedListener() { @Override public void onClick(Component component) { /* * 通过 presentForResult 实现跳转到目标AbilitySlice,并获取结果 * 参数一:要跳转的AbilitySlice * 参数二:Intent对象 * 参数三:请求码(该请求码主要是和onResult回调函数中的请求码进行匹配所用) * */ presentForResult(new ContentAbilitySlice(),new Intent(),REQUEST_CODE); } }); } @Override protected void onResult(int requestCode, Intent resultIntent) { //super.onResult(requestCode, resultIntent); // 判断是否是对应的请求码 if (requestCode == REQUEST_CODE){ // 获取返回结果数据 int result = resultIntent.getIntParam("test",0); text.setText("返回的结果数据为:"+result); } } @Override public void onActive() { super.onActive(); } @Override public void onForeground(Intent intent) { super.onForeground(intent); } }
要跳转的目标 ContentAbilitySlice.java 代码
package com.example.helloword3.slice; import com.example.helloword3.ResourceTable; import ohos.aafwk.ability.AbilitySlice; import ohos.aafwk.content.Intent; public class ContentAbilitySlice extends AbilitySlice { @Override public void onStart(Intent intent) { super.onStart(intent); super.setUIContent(ResourceTable.Layout_ability_content); // 创建Intent用于通信 Intent intent2 = new Intent(); /* 设置页面销毁后的结果数据 参数一:key 参数二:int类型的值 */ intent2.setParam("test",100); setResult(intent2); } @Override public void onActive() { super.onActive(); } @Override public void onForeground(Intent intent) { super.onForeground(intent); } }
效果图:

系统为每个Page维护了一个AbilitySlice实例的栈,每个进入前台的AbilitySlice实例均会入栈。当开发者在调用 present()或presentForResult()时指定的AbilitySlice实例已在栈中存在时,则栈中位于此实例之上的AbilitySlice均会出栈并销毁。
效果图:

实现步骤:
1、首先打开 MainAbilitySlice.java文件,然后获取按钮组件,给该组件添加一个点击事件,然后通过意图(Intent)实现页面跳转,详细代码如下:
package com.example.helloword.slice; import com.example.helloword.ResourceTable; import ohos.aafwk.ability.AbilitySlice; import ohos.aafwk.content.Intent; import ohos.aafwk.content.Operation; import ohos.agp.components.Button; import ohos.agp.components.Component; import ohos.agp.components.DirectionalLayout; import ohos.agp.components.DirectionalLayout.LayoutConfig; import ohos.agp.components.Text; import ohos.agp.colors.RgbColor; import ohos.agp.components.element.ShapeElement; import ohos.agp.utils.Color; import ohos.agp.utils.TextAlignment; public class MainAbilitySlice extends AbilitySlice { /* private DirectionalLayout myLayout = new DirectionalLayout(this);*/ @Override public void onStart(Intent intent) { super.onStart(intent); // 加载XML布局 super.setUIContent(ResourceTable.Layout_main_layout); // 通过 findComponentById 找到 id为 button 组件 Button btn = (Button) findComponentById(ResourceTable.Id_button); // 然后给这个Button组件添加一个点击事件 btn.setClickedListener(new Component.ClickedListener() { @Override public void onClick(Component component) { // 创建意图对象,用于页面跳转 Intent intent = new Intent(); // 创建Operation对象,主要用于配置Intent相关的参数 Operation operation = new Intent.OperationBuilder() .withDeviceId("") // 设置当前的设备ID, .withBundleName("com.example.helloword") // 设置Bundle的名称 .withAbilityName("com.example.helloword.MeAbility") // 设置要跳转的Ability包名 .build(); // 设置意图Operation对象 intent.setOperation(operation); // 开始跳转 startAbility(intent); } }); } @Override public void onActive() { super.onActive(); } @Override public void onForeground(Intent intent) { super.onForeground(intent); } }
效果图:

Page(Ability)间跳转
这种场景的跳转类似于Android应用间的跳转
由于不同的Page中的AbilitySlice相互不可见,因此无法通过present() 或 presentForResult() 方法直接导航到其它的 Page的 AbilitySlice。AbilitySlice作为Page的内部单元,以Action的形式对外暴露,因此可以通过配置Intent的Action导航到目标 AbilitySlice。Page间的导航可以使用 startAbility() 或 startAbilityForResult() 方法,获得返回结果的回调为 onAbilityResult()。 在Ability 中调用 setResult() 可以设置返回结果。
另外,能够跳转到其它Page(Ability)的前提是要跳转到的这个Page(Ability)需要配置对应的action
第一步:配置action:
1、首先需要在配置文件中声明对外提供的能力,以便系统据此找到自身并作为候选的请求处理着:
{ "module": { … "abilities": [ { … "skills":[ { "actions":[ "ability.intent.QUERY_WEATHER" ] } ] … } ] … } … }
2、在Ability中配置路由以便支持此action导航到对应的AbilitySlice
@Override protected void onStart(Intent intent) { … addActionRoute(Intent.ACTION_QUERY_WEATHER, DemoSlice.class.getName()); … }
3、在Ability中处理请求,并调用setResult() 方法暂存返回结果
@Override protected void onActive() { … Intent resultIntent = new Intent(); setResult(0, resultIntent); … }
进行页面间跳转,在Ability中构造Intent以及包含Action的Operation对象,并调用 startAbilityForResult() 方法发起请求,然后重写 onAbilityResult() 回调方法,对请求结果进行处理
private void queryWeather() { Intent intent = new Intent(); Operation operation = new Intent.OperationBuilder() .withAction(Intent.ACTION_QUERY_WEATHER) .build(); intent.setOperation(operation); startAbilityForResult(intent, REQ_CODE_QUERY_WEATHER); } @Override protected void onAbilityResult(int requestCode, int resultCode, Intent resultData) { switch (requestCode) { case REQ_CODE_QUERY_WEATHER: // Do something with result. … return; default: … } }
在Javascript开发模式下,页面跳转和传参
为了方便开发者在JS中进行页面跳转,HarmonyOS提供了 router API,通过该API可以完成页面之间的导航:
API | 手机 | 平板 | 智慧屏 | 智能穿戴 |
router.push | 支持 | 支持 | 支持 | 支持 |
router.replace | 支持 | 支持 | 支持 | 支持 |
router.back | 支持 | 支持 | 支持 | 支持 |
router.clear | 支持 | 支持 | 支持 | 支持 |
router.getLength | 支持 | 支持 | 支持 | 支持 |
router.getState | 支持 | 支持 | 支持 | 支持 |
注意:页面路由需要在页面渲染完成之后才能调用,在onInit 和 onReady 生命周期中页面还处于渲染阶段,在这两个生命周期方法中调用页面路由方法。
通过router.push() 跳转到指定页面
方法原型:router.push(OBJECT)
跳转到应用内的指定页面
参数说明:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
uri | string | 是 | 表示目标页面的uri,可以用以下两种格式:① 页面绝对路径,由配置文件中pages列表提供,例如:pages/index/index、pages/detail/detail ②特殊值,如果uri的值是”/”,则跳转到首页。 |
params | Object | 否 | 跳转时要同时传递到目标页面的数据,跳转到目标页面后,参数可以在页面中直接使用,如this.data1(data1为跳转时params参数中的key值)。如果目标页面中已有该字段,则其值会被传入的字段值覆盖。 |
// 在当前页面中 export default { pushPage() { router.push({ uri: 'pages/routerpage2/routerpage2', params: { data1: 'message', data2: { data3: [123, 456, 789] }, }, }); } } // 在routerpage2页面中 export default { data: { data1: 'default', data2: { data3: [1, 2, 3] } }, oInit() { console.info('showData1:' + this.data1); console.info('showData3:' + this.data2.data3); } }
说明:页面路由栈支持的最大Page数量为32
通过 router.back(OBJECT) 返回上一页面或指定的页面
参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
uri | string | 否 | 返回到指定uri的界面,如果页面栈上没有uri页面,则默认router.back()。 |
// index页面 router.push({ uri: 'pages/detail/detail', }); // detail页面 router.push({ uri: 'pages/mall/mall', }); // mall页面通过back,将返回detail页面 router.back(); // detail页面通过back,将返回index页面 router.back(); // 通过back,返回到detail页面 router.back({ uri:'pages/detail/detail' });
说明:示例中的uri字段是页面路由,由配置文件中的pages列表指定
通过 router.clear() 清空页面栈中的所有历史页面
清空页面栈中的所有历史页面,仅保留当前页面作为栈顶页面
示例:
router.clear();
通过 router.getLength() 获取当前页面栈中的页面数量
返回值:
类型 | 说明 |
---|---|
string | 页面数量,页面栈支持最大数值是32。 |
示例:
var size = router.getLength(); console.log('pages stack size = ' + size);
通过 router.getState() 获取当前页面的状态信息
返回值
参数名 | 类型 | 说明 |
---|---|---|
index | number | 表示当前页面在页面栈中的索引。说明:从栈底到栈顶,index从1开始递增。 |
name | string | 表示当前页面的名称,即对应文件名。 |
path | string | 表示当前页面的路径。 |
示例:
var page = router.getState(); console.log('current index = ' + page.index); console.log('current name = ' + page.name); console.log('current path = ' + page.path);
[/$]