赞
踩
Ability是HarmonyOS应用程序的重要组成部分,分为FA(Feature Ability)和PA(Particle Ability)两种类型,进行HarmonyOS应用开发,首先要了解Ability如何使用:
本文以JS UI框架为例
JS UI框架支持纯JavaScript、JavaScript和Java混合语言开发
JS UI框架是一种跨设备的高性能UI开发框架,支持声明式编程和跨设备多态UI,适用于手机(Phone)、平板(Tablet)、智慧屏(TV)和智能穿戴(Wearable)应用开发
JS UI框架采用类HTML和CSS声明式编程语言作为页面布局和页面样式的开发语言:
整体架构:
JS UI框架包括应用层(Application)、前端框架层(Framework)、引擎层(Engine)和平台适配层(Porting Layer)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rOOpdsJ8-1665454269979)(https://gitee.com/xu-yanbo/picture/raw/master/hm1.png)]
JS FA指基于JavaScript或JavaScript和Java混合开发的FA
新建的JS工程目录如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EI8AAMHH-1665454269981)(https://gitee.com/xu-yanbo/picture/raw/master/hm2.png)]
public class MainAbility extends AceAbility {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
}
@Override
public void onStop() {
super.onStop();
}
}
应用通过AceAbility类中**setInstanceName()**接口设置该Ability的实例资源,并通过AceAbility窗口进行显示以及全局应用生命周期管理。
setInstanceName(String name)的参数“name”指实例名称,实例名称与config.json文件中module.js.name的值对应。若开发者未修改实例名,而使用了缺省值default,则无需调用此接口。若开发者修改了实例名,则需在应用Ability实例的onStart()中调用此接口,并将参数“name”设置为修改后的实例名称。
使用方法为:在MainAbility的onStart()中的super.onStart()前调用此接口。以JSComponentName作为实例名称,代码示例如下
public class MainAbility extends AceAbility {
@Override
public void onStart(Intent intent) {
setInstanceName("JSComponentName"); // config.json配置文件中module.js.name的标签值。
super.onStart(intent);
}
}
common:该文件夹下存放了一些公共资源文件,比如:媒体资源,自定义组件和JS文件
componets:存放一些自定义组件
i18n:存放了多语言的json文件,用于配置不同语言场景资源内容,比如:应用应用文本词条,图片路径等资源,注意 i18n 是开发保留文件夹,不可重命名
{
"strings": {
"hello": "Hello",
"world": "World"
}
}
pages:pages文件夹下存放多个页面,每个页面由hml、css和js文件组成==预览的时候需要点击任一个页面才可完成==我们需要的页面都可以写在这个文件夹下面
<div class = "container">
<text class = "title">
{{ $t('strings.hello') }} {{title}}
</text>
</div>
.container {
flex-direction: column;
justify-content: center;
align-items: center;
}
.title {
font-size: 100px;
}
export default {
data: {
title: '',
},
onInit() {
this.title = this.$t('strings.world');
},
}
app.js:文件用于全局js逻辑和应用声明周期管理
resore config.json:应用配置,用于描述应用的全局配置信息、在具体设备上的配置信息和HAP的配置信息(折叠起来了)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MX7Vkg0U-1665454269981)(https://gitee.com/xu-yanbo/picture/raw/master/hm3.png)]
主体文件分为app、device、module三个部分
app:表示应用的全局配置信息
deviceConfig: 表示应用在具体设备上的配置信息
module 表示当前页面的配置信息,只对当前页面生效(比如我们可以在deviceType里修改设备类型)
"phone",
"tv",
"wearable"
应用资源可通过绝对路径或相对路径的方式进行访问,本开发框架中绝对路径以 “/” 开头,相对路径以 “./” 或 “…/” ,具体访问规则如下:
格式 | 支持版本 | 支持文件类型 |
---|---|---|
BMP | API Version 3 | .bmp |
JPEG | API Version 3 | .jpg |
PNG | API Version 3 | .png |
标签中包含了实例名称、页面路由信息,每个应用可以在 app.js 自定义应用级生命周期的实现逻辑
组件(Component)是构建页面的核心,每个组件通过对数据和方法的简单封装,实现独立的可视、可交互功能单元。组件之间相互独立,随取随用,也可以在需求相同的地方重复使用
根据组件的分类,可分为四大类
组件类型 | 主要组件 |
---|---|
基础组件 | text、image、progress、rating、span、marquee、image-animator、divider、search、menu、chart |
容器组件 | div、list、list-item、stack、swiper、tabs、tab-bar、tab-content、list-item-group、refresh、dialog |
媒体组件 | video |
画布组件 | canvas |
相关使用方法可查官方文档
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WvUDcAXM-1665454269982)(https://gitee.com/xu-yanbo/picture/raw/master/hm4.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mTnjoITh-1665454269983)(https://gitee.com/xu-yanbo/picture/raw/master/hm5.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rN78PTUK-1665454269984)(https://gitee.com/xu-yanbo/picture/raw/master/hm6.png)]
注:组件里展示的图片需要开发者自行添加图片资源,放置到“js > default > common”目录下,common目录需自行创建
/*
在phone 设备上1px = 3物理像素
在tv 设备上1px = 2物理像素
在穿戴设备上 1px = 2物理像素
*/
一个页面的基本元素包含标题区域、文本区域、图片区域等,每个基本元素内还可以包含多个子元素,开发者根据需求还可以添加按钮、开关、进度条等组件。在构建页面布局时,需要对每个基本元素思考以下几个问题:
实现标题和文本区域最常用的是基础组件text。text组件用于展示文本,可以设置不同的属性和样式,文本内容需要写在标签内容区,完整属性和样式信息请参考官方文档,代码示例如下
<!-- xxx.hml -->
<div class="container">
<text class="title-text">{{headTitle}}</text>
<text class="paragraph-text">{{paragraphFirst}}</text>
<text class="paragraph-text">{{paragraphSecond}}</text>
</div>
/* xxx.css */ .container { flex-direction: column; margin-top: 20px; margin-left: 30px; } .title-text { color: #1a1a1a; font-size: 50px; margin-top: 40px; margin-bottom: 20px; } .paragraph-text { color: #000000; font-size: 35px; line-height: 60px; }
// xxx.js
export default {
data: {
headTitle: 'Capture the Beauty in This Moment',
paragraphFirst: 'Capture the beauty of light during the transition and fusion of ice and water. At the instant of movement and stillness, softness and rigidity, force and beauty, condensing moving moments.',
paragraphSecond: 'Reflecting the purity of nature, the innovative design upgrades your visual entertainment and ergonomic comfort. Effortlessly capture what you see and let it speak for what you feel.',
},
}
添加图片区域通常用image组件来实现,使用的方法和text组件类似。图片资源建议放在“js > default > common”目录下,详细代码如下:
<!-- xxx.hml -->
<image class="img" src="{{middleImage}}"></image>
/* xxx.css */
.img {
margin-top: 30px;
margin-bottom: 30px;
height: 385px;
}
// xxx.js
export default {
data: {
middleImage: '/common/xxx.png',
},
}
要将页面的基本元素组装在一起,需要使用容器组件。在页面布局中常用到三种容器组件,分别是div、list和tabs。在页面结构相对简单时,可以直接用div作为容器,因为div作为单纯的布局容器,可以支持多种子组件,使用起来更为方便
list组件
当页面结构较为复杂时,如果使用div循环渲染,容易出现卡顿,因此推荐使用list组件代替div组件实现长列表布局,从而实现更加流畅的列表滚动体验。需要注意的是,list仅支持list-item作为子组件,具体的使用示例如下:
<!-- xxx.hml -->
<list class="list">
<list-item type="listItem" for="{{textList}}">
<text class="desc-text">{{$item.value}}</text>
</list-item>
</list>
/* xxx.css */
.desc-text {
width: 683.3px;
font-size: 35.4px;
}
// xxx.js
export default {
data: {
textList: [{value: 'JS FA'}],
},
}
示例中list中只包含一个list-item,list-item中只有一个text组件。在实际应用中可以在list中加入多个list-item,同时list-item下可以包含多个其他子组件
Tabs组件
当页面经常需要动态加载时,推荐使用tabs组件。tabs组件支持change事件,在页签切换后触发。tabs组件仅支持一个tab-bar和一个tab-content。具体的使用示例如下
<!-- xxx.hml -->
<tabs>
<tab-bar>
<text>Home</text>
<text>Index</text>
<text>Detail</text>
</tab-bar>
<tab-content>
<image src="{{homeImage}}"></image>
<image src="{{indexImage}}"></image>
<image src="{{detailImage}}"></image>
</tab-content>
</tabs>
// xxx.js
export default {
data: {
homeImage: '/common/home.png',
indexImage: '/common/index.png',
detailImage: '/common/detail.png',
},
}
tab-content组件用来展示页签的内容区,高度默认充满tabs剩余空间。tab-content支持scrollable属性,详见官网具体属性
我们可以在pages文件夹下的index.hml文件中构建页面布局,这里注意不是 HTML,而是 HML,并且文件名也是 hml 结尾。因为鸿蒙的运行环境并不是浏览器,所以不支持原生的 html 标签,虽然有些标签名字一样,但那些只是鸿蒙为了便利开发者而定的,底层实现完全不一样,它们会转换成原生的鸿蒙控件,当然它也有特殊的 hml 标签,方便进行布局。语法上,除了一些 html 属性不支持外,其他都一样。这一点,跟 React Native 的原理是一样的。鸿蒙支持的标签可以查看 API 文档
在进行代码开发之前,首先要对页面布局进行分析,将页面分解为不同的部分,用容器组件来承载
<text>
标签中才能呈现,否则不会呈现文本内容鸿蒙中的 CSS 与普通的 CSS 还是有一些区别的,有些属性用法不同,并且不同的标签对于 CSS 属性的支持程度也不一样,可以参考 HML 部分中提到的 API 文档。在鸿蒙 TV 项目中,容器默认是 flex 布局,并且 flex-direction 为 row,行方向,这个需要注意一下
比如先给 text 标签设置默认的文本颜色,text 标签的 css 代码如下:
text {
color: #414873;
}
其他的样式可以参考官方示例
可在pages里的index.js文件中构建页面逻辑,这里的语法和方式跟 Vue 一样
很多应用由多个页面组成,比如用户可以从音乐列表页面点击歌曲,跳转到该歌曲的播放界面。开发者需要通过页面路由将这些页面串联起来,按需实现跳转。
页面路由router根据页面的uri来找到目标页面,从而实现跳转。以最基础的两个页面之间的跳转为例,具体实现步骤如下:
比如我们要在pages文件夹下构建index的detail这两个页面均包含一个text组件和button组件:text组件用来指明当前页面,button组件用来实现两个页面之间的相互跳转。hml文件代码示例如下
<!-- index.hml -->
<div class="container">
<text class="title">This is the index page.</text>
<button type="capsule" value="Go to the second page" class="button" onclick="launch"></button>
</div>
<!-- detail.hml -->
<div class="container">
<text class="title">This is the detail page.</text>
<button type="capsule" value="Go back" class="button" onclick="launch"></button>
</div>
构建index和detail页面的页面样式,text组件和button组件居中显示,两个组件之间间距为50px。css代码如下(两个页面样式代码一致)
/* index.css */
/* detail.css */
.container {
flex-direction: column;
justify-content: center;
align-items: center;
}
.title {
font-size: 50px;
margin-bottom: 50px;
}
为了使button组件的launch方法生效,需要在页面的js文件中实现跳转逻辑。调用router.push()接口将uri指定的页面添加到路由栈中,即跳转到uri指定的页面。在调用router方法之前,需要导入router模块。代码示例如下:
// index.js
import router from '@system.router';
export default {
launch() {
router.push ({
uri: 'pages/detail/detail',
});
},
}
// index.js
import router from '@system.router';
export default {
launch() {
router.push ({
uri: 'pages/detail/detail',
});
},
}
JS UI框架支持自定义组件,用户可根据业务需求将已有的组件进行扩展,增加自定义的私有属性和事件,封装成新的组件,方便在工程中多次调用,提高页面布局代码的可读性:
// common.datas.tabbarItem.js export default [ { img:'common/images/home.png', simg:'common/images/home_s.png', name:'首页' }, { img:'common/images/hot.png', simg:'common/images/hot_s.png', name:'热点' }, { img:'common/images/us.png', simg:'common/images/us_s.png', name:'社区' }, { img:'common/images/me.png', simg:'common/images/me_s.png', name:'我' } ]
<div class="container">
<toolbar class="tabbar">
<toolbar-item for="{{tabbarItems}}" icon='{{$item.img}}' value='{{$item.name}}' onclick="jump($idx)" ></toolbar-item>
</toolbar>
</div>
import tabbarItems from '../../common/datas/tabbarItem.js';
export default {
data:{
tabbarItems
},
jump(index){
this.tabbarItems.forEach((item,index) => {
item.img = tabbarItems[index].img;
});
this.tabbarItems[index].img = this.tabbarItems[index].simg;
}
}
.tabbar {
position: fixed;
left: 0;
bottom: 0;
}
自定义组件是用户根据业务需求,将已有的组件组合,封装成的新组件,可以在工程中多次调用,提高代码的可读性
自定义组件通过element引入到宿主页面,使用方法:
<element name='comp' src='../../components/tabbar/tabbar.hml'></element>
<div class="container">
<text class="title">
首页
</text>
<comp></comp>
</div>
以上部分摘自鸿蒙开发官方文档
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。