HarmonyOS Sample 之 PageAbility页面导航及迁移 原创 精华

Buty9147
发布于 2021-6-29 20:08
浏览
3收藏

@toc

PageAbility页面导航及迁移

介绍

本示例实现了以下几个功能:
1.同一Page Ability内不同Slice导航
2.不同Page间的AbilitySlice导航
3.Page Ability的跨端迁移

搭建环境

安装DevEco Studio,详情请参考DevEco Studio下载
设置DevEco Studio开发环境,DevEco Studio开发环境需要依赖于网络环境,需要连接上网络才能确保工具的正常使用,可以根据如下两种情况来配置开发环境:

如果可以直接访问Internet,只需进行下载HarmonyOS SDK操作。
如果网络不能直接访问Internet,需要通过代理服务器才可以访问,请参考配置开发环境

代码结构解读

后台逻辑

pageability
  │  ContinuationAbility.java 	#迁移Ability 示例
  │  FirstAbility.java 		#同一Page Ability内不同Slice导航 示例
  │  MainAbility.java 		#主Ability
  │  MyApplication.java 	#启动入口
  │  SecondAbility.java 	#不同Page间的AbilitySlice导航 示例
  │
  └─slice
          ContinuationAbilitySlice.java #迁移Slice
          FirstAbilityMainSlice.java 	#FirstAbility的默认Slice
          FirstAbilitySecondSlice.java 	#FirstAbility的第二个Slice
          MainAbilitySlice.java		#MainAbility默认Slice
          SecondAbilityMainSlice.java   #SecondAbility的默认Slice
          SecondAbilitySecondSlice.java #SecondAbility的第二个Slice

页面布局

├─layout
│      continuation_ability.xml 	#迁移页面布局
│      first_ability_main_slice.xml	#FirstAbilityMainSlice的页面布局
│      first_ability_second_slice.xml 	#FirstAbilitySecondSlice的页面布局
│      main_ability_slice.xml		#MainAbilitySlice的页面布局
│      second_ability_main_slice.xml	#SecondAbilityMainSlice的页面布局
│      second_ability_second_slice.xml	#SecondAbilitySecondSlice的页面布局

页面布局

布局比较简单,我就贴个运行的效果图大家就清楚了
HarmonyOS Sample 之 PageAbility页面导航及迁移-鸿蒙开发者社区

后台逻辑

1.同一Page Ability内不同Slice导航

有两种情况,
第一,需要返回数据就使用presentForResult方法,

//监听按钮点击事件
presentButton.setClickedListener(
  //启动同一Page Ability的其它slice(lambda表达式的写法)
  component -> presentForResult(new FirstAbilitySecondSlice(), new Intent(),REQUEST_CODE));

/**
 * 从其它slice返回数据时,回调此函数
 * @param requestCode
 * @param resultIntent
 */
@Override
protected void onResult(int requestCode, Intent resultIntent) {
  //可以做安全验证
  if (requestCode == REQUEST_CODE && resultIntent != null) {
     //根据key从Intent中获取从其它slice返回的数据并显示
     messageText.setText(resultIntent.getStringParam(FirstAbilitySecondSlice.RESULT_KEY));
  }
} 

目标Slice把数据存到Intent中,当执行terminate()方法时,就会执行回调onResult方法

public class FirstAbilitySecondSlice extends AbilitySlice {
   
  public static final String RESULT_KEY = "ohos.samples.pageability.data";

    @Override
    protected void onStart(Intent intent) {
      super.onStart(intent);
      super.setUIContent(ohos.samples.pageability.ResourceTable.Layout_first_ability_second_slice);
      initComponents();
      //设置返回数据
      setResult();
    }

    /**
     * 存储要传递的数据到Intent
     */
    private void setResult() {
        Intent intent = new Intent();
        intent.setParam(RESULT_KEY, "{name:'zhangsan',age:20}");
        //当能力切片调用 terminate() 方法时,将当前方法设置的结果数据传递给调用者。
        setResult(intent);
    }
}

第二,不需要返回数据就用present方法就可以了

//监听按钮点击事件
presentButton.setClickedListener(
     //启动同一Page Ability的其它slice,不需要返回数据
     component -> present(new FirstAbilitySecondSlice(), new Intent()));

2.不同Page间的AbilitySlice导航,需要借助Operation的设置

也分两种,
第一,导航到目标Ability的默认Slice,不需要指定Operation的Action,或者设置为空

//启动不同Page间的AbilitySlice,默认slice
startSecondButton.setClickedListener(this::startSecondAbilitySlice);
/**
 * 导航到Page默认的slice页面
 * @param component
 */
private void startSecondAbilitySlice(Component component) {
    Intent intent = new Intent();
    Operation operation = new Intent.OperationBuilder().withDeviceId("")
            //空代表默认路由,也就是默认的slice
            .withAction("")
            .withBundleName(getBundleName())
            .withAbilityName(SecondAbility.class.getName())
            .build();
    intent.setOperation(operation);
    //启动
    startAbility(intent);
}

第二,导航到目标Ability的非默认页,指定Action,需要借助路由实现

//监听事件,启动不同Page间的AbilitySlice,非默认slice
presentSecondButton.setClickedListener(this::startAbilitySlice);

/**
 * 如果导航的slice不是Page默认的slice,
 * 需要根据设置的路由进行导航
 * @param component
 */
private void startAbilitySlice(Component component) {
    Intent intent = new Intent();
    Operation operation = new Intent.OperationBuilder().withDeviceId("")
            //指定导航路由
            .withAction(ACTION)
            .withBundleName(getBundleName())
            .withAbilityName(SecondAbility.class.getName())
            .build();
    intent.setOperation(operation);
    //启动
    startAbility(intent);
}

路由不是随便写的,需要在config.json注册 ,同时,在对应的SecondAbility中设置

HarmonyOS Sample 之 PageAbility页面导航及迁移-鸿蒙开发者社区
HarmonyOS Sample 之 PageAbility页面导航及迁移-鸿蒙开发者社区

3.Page Ability的跨端迁移

1.config.json 声明多设备协同权限
HarmonyOS Sample 之 PageAbility页面导航及迁移-鸿蒙开发者社区

2.ContinuationAbility 请求用户授权
HarmonyOS Sample 之 PageAbility页面导航及迁移-鸿蒙开发者社区

3.ContinuationAbility 处理用户接受/拒绝 授权后的回调函数
需要implements IAbilityContinuation接口,重写onRequestPermissionsFromUserResult方法

HarmonyOS Sample 之 PageAbility页面导航及迁移-鸿蒙开发者社区

4.ContinuationAbility 处理其它协同函数
HarmonyOS Sample 之 PageAbility页面导航及迁移-鸿蒙开发者社区

5.ContinuationAbilitySlice 迁移数据处理
同样需要implements IAbilityContinuation接口,重新相关方法。
从终端A 迁移到 终端B 的整个过程:
A端:
在onStart方法中初始化迁移监听事件,监听事件里调用continueAbility()方法启动迁移,
开始迁移时,回调onStartContinuation方法确认是否迁移,然后回调在onSaveData方法保存迁移数据,返回是否成功,
成功后,向对端发起迁移请求。
B端:
执行回调函数onRestoreData 恢复数据,返回是否成功,通知A端迁移成功
A端:
执行回调函数onCompleteContinuation 迁移完成,关闭当前Slice
HarmonyOS Sample 之 PageAbility页面导航及迁移-鸿蒙开发者社区

归纳总结

1.迁移过程数据的存储和恢复

@Override
public boolean onSaveData(IntentParams intentParams) {
    HiLog.debug(LABEL_LOG, "onSaveData");
    //迁移时,设置需要传递的数据
    intentParams.setParam(MESSAGE_KEY, messageTextField.getText());
    return true;
}
@Override
public boolean onRestoreData(IntentParams intentParams) {
    HiLog.debug(LABEL_LOG, "onRestoreData");
    //验证返回数据类型
    if (intentParams.getParam(MESSAGE_KEY) instanceof String) {
        //获取待恢复的数据
        message = (String) intentParams.getParam(MESSAGE_KEY);
        //恢复成功
        isContinued = true;
    }
    return true;
}

2.迁移数据的回显

迁移后往往需要把A端的数据在B端的页面回显,不要在onRestoreData回调中设置,而是把数据赋值给全局变量,然后在onStart方法中进行设置。

效果展示

HarmonyOS Sample 之 PageAbility页面导航及迁移-鸿蒙开发者社区

完整代码

附件直接下载

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
PageAbility.zip 1.64M 264次下载
已于2021-6-29 20:08:29修改
6
收藏 3
回复
举报
3条回复
按时间正序
/
按时间倒序
mb609898e2cfb86
mb609898e2cfb86

很详细的解读,谢谢分享。

回复
2021-6-30 10:26:48
mark475
mark475

很详细的解读,谢谢分享。
 

回复
2021-7-1 11:32:32
爱吃土豆丝的打工人
爱吃土豆丝的打工人

解读的很详细,适合新手开发的理解~  感谢分享

回复
2021-7-1 16:03:23
回复
    相关推荐