HarmonyOS Sample 之 PageAbility页面导航及迁移 原创 精华
@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的页面布局
页面布局
布局比较简单,我就贴个运行的效果图大家就清楚了
后台逻辑
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中设置
3.Page Ability的跨端迁移
1.config.json 声明多设备协同权限
2.ContinuationAbility 请求用户授权
3.ContinuationAbility 处理用户接受/拒绝 授权后的回调函数
需要implements IAbilityContinuation接口,重写onRequestPermissionsFromUserResult方法
4.ContinuationAbility 处理其它协同函数
5.ContinuationAbilitySlice 迁移数据处理
同样需要implements IAbilityContinuation接口,重新相关方法。
从终端A 迁移到 终端B 的整个过程:
A端:
在onStart方法中初始化迁移监听事件,监听事件里调用continueAbility()方法启动迁移,
开始迁移时,回调onStartContinuation方法确认是否迁移,然后回调在onSaveData方法保存迁移数据,返回是否成功,
成功后,向对端发起迁移请求。
B端:
执行回调函数onRestoreData 恢复数据,返回是否成功,通知A端迁移成功
A端:
执行回调函数onCompleteContinuation 迁移完成,关闭当前Slice
归纳总结
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方法中进行设置。
效果展示
完整代码
附件直接下载
很详细的解读,谢谢分享。
很详细的解读,谢谢分享。
解读的很详细,适合新手开发的理解~ 感谢分享