鸿蒙FA开发之JSUI与JavaUI相互跳转实例

系统 OpenHarmony
鸿蒙官方推荐使用Js或eTS方式来开发APP应用UI,但在开发过程中有可能会遇到JSUI无法实现的功能。

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​

需求背景说明

鸿蒙官方推荐使用Js或eTS方式来开发APP应用UI,但在开发过程中有可能会遇到JSUI无法实现的功能,例如地图导航、定制化视频播放器,那么这种场景下如何实现功能,这个需求就带来如下问题:

1.一个页面是否能同时使用JavaUI和JSUI,JSUI来实现简单功能,JavaUI来实现定制化功能。

2.一个工程是否支持不同的UI语法,比如PageA使用JSUI,PageB使用JavaUI。

带着问题我们来回顾一下鸿蒙开发支持的UI开发方式。

1、Java UI

使用xml方式描述UI界面布局,应用中所有的用户界面元素都是由Component和ComponentContainer对象构成。Component是绘制在屏幕上的一个对象,用户能与之交互。ComponentContainer是一个用于容纳其他Component和ComponentContainer对象的容器。Java UI框架提供了一部分Component和ComponentContainer的具体子类,即创建用户界面(UI)的各类组件,包括一些常用的组件(比如:文本、按钮、图片、列表等)和常用的布局(比如:DirectionalLayout和DependentLayout)。用户可通过组件进行交互操作,并获得响应。

#夏日挑战赛#鸿蒙FA开发之JSUI与JavaUI相互跳转实例-开源基础软件社区

2、JS UI

基于JS扩展的类Web开发范式的方舟开发框架是一种跨设备的高性能UI开发框架,支持声明式编程和跨设备多态UI。 采用类HTML和CSS Web编程语言作为页面布局和页面样式的开发语言,页面业务逻辑则支持ECMAScript规范的JavaScript语言。方舟开发框架提供的类Web编程范式,可以让开发者避免编写UI状态切换的代码,视图配置信息更加直观。

#夏日挑战赛#鸿蒙FA开发之JSUI与JavaUI相互跳转实例-开源基础软件社区

3、eTS UI

使用基于TS扩展的声明式开发范式的方舟开发框架,采用更接近自然语义的编程方式,让开发者可以直观地描述UI界面,不必关心框架如何实现UI绘制和渲染,实现极简高效开发。从组件、动效和状态管理三个维度来提供UI能力,还提供了系统能力接口,实现系统能力的极简调用。

#夏日挑战赛#鸿蒙FA开发之JSUI与JavaUI相互跳转实例-开源基础软件社区

根据Ability的分类来考虑,JsUI继承自AceAbility,而JavaUI使用xml方式进行渲染,它继承自Ability,所以在同一界面上使用两个语言在页面渲染器就已经决定了,JavaUI和JSUI不能在同一Page中使用。

那么问题2是否可行呢,答案是可以的。因为PageA和PageB可以用2个不同的Ability来渲染实现。

需要实现PageA是应用主页面,使用JSUI实现,PageA上有个按钮跳转到PageB,PageB展示地图导航页面,PageB使用JavaUI实现

如图:

#夏日挑战赛#鸿蒙FA开发之JSUI与JavaUI相互跳转实例-开源基础软件社区

JSUI自带有router功能,可以通过router.push进行跳转,但这仅限于JSUI的不通页面,对于上述场景行不通。

那么只能使用ability的startAbility能力来实现不同ability之前的跳转。

使用AceInternalAbility来接收页面的跳转请求,然后通过ability的startAbility方法跳转到另一个ability,流程图如下:

#夏日挑战赛#鸿蒙FA开发之JSUI与JavaUI相互跳转实例-开源基础软件社区

代码实现

MainAbility.java:

@Override
public void onStart(Intent intent) {
……
// 注册AceInternalAbility,接收首页按钮请求
TransInternalAbility.getInstance().register(this);
super.onStart(intent);
}
}

TransInternalAbility.java:

private static final String BUNDLE_NAME = "cn.pmagroup.ble.pmap30";
private static final String MAP_ABILITY_NAME = "cn.pmagroup.ble.pmap30.ability.MapAbility";
private static final String ABILITY_NAME = "cn.pmagroup.ble.pmap30.ability.TransInternalAbility";
private static final int SUCCESS = 0;
private static final int ERROR = 1;
private static final int PULL_MAP_PAGE = 1001;
// 定义日志标签
private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0, "MY_TAG");
private static TransInternalAbility instance;
private Ability ability;
private TransInternalAbility() {
super(BUNDLE_NAME, ABILITY_NAME);
}
public static TransInternalAbility getInstance() {
if (instance == null) {
synchronized (TransInternalAbility.class) {
if (instance == null) {
instance = new TransInternalAbility();
}
}
}
return instance;
}
public static void register(Ability ability) {
HiLog.info(LABEL, "DataHandlerAbility: register");
if (ability == null) {
HiLog.info(LABEL, "register abilityContext is null");
} else {
HiLog.info(LABEL, "register " + ability.getBundleName());
if (instance == null) {
instance = new TransInternalAbility();
}
instance.onRegister(ability);
}
}
/**
* init Internal ability
*/
public void onRegister(Ability ability) {
this.ability = ability;
this.setInternalAbilityHandler(this::onRemoteRequest);
}
private boolean onRemoteRequest(int code, MessageParcel data, MessageParcel reply, MessageOption option) {
HiLog.info(LABEL, "DataHandlerAbility: onRemoteRequest");
String dataString = data.readString();
switch (code) {
case PULL_MAP_PAGE: {
reply.writeString("{ code: 0 }");
// 拉起地图导航JavaUI ability
this.pullMapPage();
break;
}
default: {
reply.writeString("service not defined");
return false;
}
}
return true;
}
// 拉起地图导航JavaUI ability
private void pullMapPage() {
Intent intent = new Intent();
Operation operation = new Intent.OperationBuilder().withBundleName(BUNDLE_NAME)
.withAbilityName(MAP_ABILITY_NAME).build();
intent.setOperation(operation);
this.ability.startAbilityForResult(intent, PULL_MAP_PAGE);
}
}

MapAbility.java:

private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0, "MAP_ABILITY");
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setMainRoute(MapAbilitySlice.class.getName());
}
}

MapAbilitySlice.java:

private static final int TOAST_DURATION = 3500;
private static final String BUNDLE_NAME = "cn.pmagroup.ble.pmap30";
private static final String CONTROL_ABILITY = "cn.pmagroup.ble.pmap30.ability.MainAbility";
private static final int VP2PX_VALUE = 64;
private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0, "MAP_ABILITY_SLICE");
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_map_ability);
this.initComponents();
}
private void initComponents() {
Button btnGoBack = (Button) findComponentById(ResourceTable.Id_btn_goBack);
ShapeElement background = new ShapeElement();
background.setRgbColor(new RgbColor(0, 125, 255));
background.setCornerRadius(25);
btnGoBack.setBackground(background);
// 在组件中增加对点击事件的检测
btnGoBack.setClickedListener(component -> {
// 此处添加按钮被点击需要执行的操作
LogUtil.debug("JavaUI", "btnGoBack click");
this.showToast(this, "返回控制页面");
this.goBack2ControlPage();
});
}
private void goBack2ControlPage() {
Intent intent = new Intent();
Operation operation = new Intent.OperationBuilder().withBundleName(BUNDLE_NAME)
.withAbilityName(CONTROL_ABILITY).build();
intent.setOperation(operation);
startAbility(intent);
}
@Override
public void onActive() {
super.onActive();
}
@Override
public void onForeground(Intent intent) {
super.onForeground(intent);
}
}

map_ability.xml(Layout文件):

<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:alignment="center"
ohos:orientation="vertical">
<Text
ohos:id="$+id:text_helloworld"
ohos:height="match_content"
ohos:width="match_content"
ohos:background_element="$graphic:background_ability_test"
ohos:layout_alignment="horizontal_center"
ohos:text="$string:testability_HelloWorld"
ohos:text_size="40vp"
/>
<Button
ohos:id="$+id:btn_goBack"
ohos:height="40vp"
ohos:width="match_parent"
ohos:text="返回"
ohos:text_size="20vp"
ohos:focus_border_enable="true"
/>
</DirectionalLayout>

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​​。

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2021-08-04 14:16:41

鸿蒙HarmonyOS应用

2009-07-02 15:02:44

JSP Servlet自动跳转

2021-09-23 14:39:28

鸿蒙HarmonyOS应用

2013-05-20 17:13:17

Android游戏开发CanvasPaint

2011-04-12 08:40:23

IMFAndroid

2011-08-22 13:46:15

iPhone开发GameKit 蓝牙

2011-08-03 16:22:05

Objective-C CodeBlocks

2013-05-21 11:26:49

Android游戏开发Sensor感应

2012-08-15 10:16:40

云计算数据中心虚拟化

2015-03-30 14:03:13

ActivityGroActivity跳转

2012-12-24 09:09:27

AndoidUnity3D

2021-03-25 15:54:14

鸿蒙HarmonyOS应用开发

2011-08-03 16:01:24

iPhone应用开发 自动登陆

2009-08-24 15:56:28

C#项目开发实例

2013-05-21 09:56:15

2009-07-03 17:39:20

JSP与EJB

2013-05-20 17:51:47

Android游戏开发SurfaceView

2010-04-20 14:13:08

Unix操作系统

2021-01-05 10:35:04

鸿蒙HarmonyOS应用开发

2021-09-03 15:08:06

鸿蒙HarmonyOS应用
点赞
收藏

51CTO技术栈公众号