鸿蒙FA开发的JSUI和JavaUI相互跳转示例需求背景说明鸿蒙官方推荐使用Js或者eTS开发APP应用UI,但是在开发过程中,可能会遇到JSUI无法实现的功能,比如地图导航和自定义视频播放器,那么这个场景下如何实现功能,这个需求带来了以下问题:1、一个页面是否可以同时使用JavaUI和JSUI,JSUI实现简单功能,JavaUI实现自定义功能。2、项目是否支持不同的UI语法,比如PageA使用JSUI,PageB使用JavaUI。带着疑问,我们来回顾一下鸿蒙开发支持的UI开发方式。1、JavaUI使用xml来描述UI界面布局。应用程序中的所有用户界面元素均由Component和ComponentContainer对象组成。组件是绘制在屏幕上的用户可以与之交互的对象。ComponentContainer是一个容器,用于容纳其他Component和ComponentContainer对象。JavaUI框架提供了Component和ComponentContainer的一些具体子类,即创建用户界面(UI)的各种组件,包括一些常用组件(如:文本、按钮、图片、列表等)和常用组件布局(例如:DirectionalLayout和DependentLayout)。用户可以与组件交互并获得响应。2.JSUI方舟开发框架基于JS扩展的类Web开发范式,是一个支持声明式编程和跨设备多态UI的跨设备高性能UI开发框架。采用HTML和CSSWeb编程语言作为页面布局和页面样式的开发语言,页面业务逻辑支持ECMAScript标准的JavaScript语言。方舟开发框架提供的类Web编程范式,让开发者无需为UI状态切换编写代码,视图配置信息更加直观。3、eTSUI使用基于TS扩展声明式开发范式的方舟开发框架,采用更接近自然语义的编程方式,让开发者可以直观地描述UI界面,无需关心框架如何实现UI绘制和渲染,实现简单性和效率发展。从组件、动画效果、状态管理三个维度提供UI能力,同时提供系统能力接口,实现系统能力的最小化调用。按照Ability的分类,JsUI继承自AceAbility,JavaUI使用xml渲染,继承自Ability,所以在页面渲染器上已经决定了同一个界面使用两种语言。JavaUI和JSUI不能在同一个页面。用在。那么问题2可行吗?答案是肯定的。因为PageA和PageB可以用两种不同的Abilities来渲染。需要实现的是PageA是应用的主页面,使用JSUI实现。PageA上有个按钮可以跳转到PageB,PageB显示地图导航页面。PageB使用JavaUI实现如图:JSUI自带router功能,可以通过router.push进行跳转,但这仅限于JSUI不可用的页面,对上述场景不起作用。那么就只能使用能力的startAbility能力来实现不同能力之前的跳转了。使用AceInternalAbility接收页面的跳转请求,然后通过能力的startAbility方法跳转到另一个能力。流程图如下:代码实现MainAbility.java:@OverridepublicvoidonStart(Intentintent){...//注册AceInternalAbility,接收主页按钮请求TransInternalAbility.getInstance().register(this);super.onStart(意图);}}TransInternalAbility.java:privatestaticfinalStringBUNDLE_NAME="cn.pmagroup.ble.pmap30";privatestaticfinalStringMAP_ABILITY_NAME="cn.pmagroup.ble.pmap30.ability.MapAbility";privatestaticfinalStringABILITY_NAME="cn.pmagroup.ble.pmap30.ability.TransInternalAbility";私有静态最终int成功=0;私有静态最终int错误=1;privatestaticfinalintPULL_MAP_PAGE=1001;//定义日志标签privatestaticfinalHiLogLabelLABEL=newHiLogLabel(HiLog.LOG_APP,0,"MY_TAG");私有静态TransInternalAbility实例;私有Ability能力;私有TransInternalLESuperNAD(){我,ABILITY_NAME);}publicstaticTransInternalAbilitygetInstance(){if(instance==null){synchronized(TransInternalAbility.class){if(instance==null){instance=newTransInternalAbility();}}}返回实例;}publicstaticvoidregister(Abilityability){HiLog.info(LABEL,"DataHandlerAbility:register");if(ability==null){HiLog.info(LABEL,"注册abilityContext为null");}else{HiLog.info(LABEL,"注册"+ability.getBundleName());if(instance==null){instance=newTransInternalAbility();}instance.onRegister(能力);}}/***初始化内部能力*/publicvoidonRegister(Abilityability){this.ability=ability;this.setInternalAbilityHandler(this::onRemoteRequest);}privatebooleanonRemoteRequest(intcode,MessageParceldata,MessageParcelreply,MessageOptionoption){HiLog.info(LABEL,"DataHandlerAbility:onRemoteRequest");字符串dataString=data.readString();switch(code){casePULL_MAP_PAGE:{reply.writeString("{code:0}");//拉起地图导航JavaUI能力this.pullMapPage();休息;}default:{reply.writeString("服务未定义");返回假;}}返回真;}//拉起地图导航JavaUI能力privatevoidpullMapPage(){Intentintent=newIntent();操作operation=newIntent.OperationBuilder().withBundleName(BUNDLE_NAME).withAbilityName(MAP_ABILITY_NAME).build();intent.setOperation(操作);this.ability.startAbilityForResult(intent,PULL_MAP_PAGE);}}MapAbility.java:privatestaticfinalHiLogLabelLABEL=newHiLogLabel(HiLog.LOG_APP,0,"MAP_ABILITY");@OverridepublicvoidonStart(Intentintent){super.onStart(intent);super.setMainRoute(MapAbilitySlice.class.getName());}}MapAbilitySlice.java:privatestaticfinalintTOAST_DURATION=3500;privatestaticfinalStringBUNDLE_NAME="cn.pmagroup.ble.pmap30";privatestaticfinalStringCONTROL_ABILITY="cn.pmagroup.ble.pmap30.ability.MainAbility";privatestaticfinalintVP2PX_VALUE=64;privatestaticfinalHiLogLabelLABEL=newHiLogLabel(HiLog.LOG_APP,0,"MAP_ABILITY_SLICE");@OverridepublicvoidonStart(Intentintent){super.onStart(intent);super.setUIContent(ResourceTable.Layout_map_ability);这个.initComponents();}privatevoidinitComponents(){ButtonbtnGoBack=(Button)findComponentById(ResourceTable.Id_btn_goBack);ShapeElement背景=新ShapeElement();background.setRgbColor(newRgbColor(0,125,255));background.setCornerRadius(25);btnGoBack.setBackground(背景);//给组件添加点击事件检测btnGoBack.setClickedListener(component->{//这里添加点击按钮时需要执行的操作LogUtil.debug("JavaUI","btnGoBackclick");this.showToast(this,"返回控制页面");this.goBack2Con??trolPage();});}privatevoidgoBack2Con??trolPage(){Intentintent=newIntent();操作operation=newIntent.OperationBuilder().withBundleName(BUNDLE_NAME).withAbilityName(CONTROL_ABILITY).build();intent.setOperation(操作);启动能力(意图);}@OverridepublicvoidonActive(){super.onActive();}@OverridepublicvoidonForeground(Intentintent){super.onForeground(intent);}}map_ability.xml(布局文件):
