华为鸿蒙HarmonyOS — 实现页面跳转和传参

在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)

跳转到应用内的指定页面

参数说明:

参数名类型必填说明
uristring表示目标页面的uri,可以用以下两种格式:① 页面绝对路径,由配置文件中pages列表提供,例如:pages/index/index、pages/detail/detail
②特殊值,如果uri的值是”/”,则跳转到首页。
paramsObject跳转时要同时传递到目标页面的数据,跳转到目标页面后,参数可以在页面中直接使用,如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) 返回上一页面或指定的页面

参数:

参数名类型必填说明
uristring返回到指定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() 获取当前页面的状态信息

返回值

参数名类型说明
indexnumber表示当前页面在页面栈中的索引。说明:从栈底到栈顶,index从1开始递增。
namestring表示当前页面的名称,即对应文件名。
pathstring表示当前页面的路径。

示例:

var page = router.getState();
 console.log('current index = ' + page.index);
 console.log('current name = ' + page.name);
 console.log('current path = ' + page.path);

[/$]

如果觉得文章有帮助到你,可以扫描以下二维码
   请本文作者 喝一杯
pay_weixin pay_weixin

发表评论

电子邮件地址不会被公开。 必填项已用*标注