ArkUI(方舟UI框架)介绍
ArkUI能力介绍
ArkUI:提供HarmonyOS应用开发框架,极简开发、精致体验、跨设备/跨平台
ArkUI(方舟UI框架):为HarmoneyOS应用的UI开发提供了完整的基础设施,包括简洁的UI语法,丰富的UI功能(组件、布局、动画以及交互事件),以及实时界面预览工具等,可以支持开发者进行丰富页面的开发。
深度融合语言/编译器/图形,构建关键的应用UI开发底座:
- 开发模型层:提供了UI开发范式的基础语言规范,并提供了多种状态管理机制,为应用开发者提供一系列接口支持。
- 引擎层:后端引擎提供了兼容不同开发范式的UI渲染管线,提供多种基础组件、布局计算、动效、交互事件,提供了状态管理和绘制能力。提供了高效地绘制能力,将渲染管线收集的渲染指令绘制到屏幕能力
- 平台抽象层:提供了针对不同操作系统渲染层的适配,可抹平不同平台的接口差异,实现ArkUI框架多平台一致性。
声明式UI范式
ArkTS:是UI开发语言,基于TS语言扩展而来,是TS的超集。扩展能力包含各种装饰器、自定义组件、UI描述机制。
声明式开发范式:基于ArkTS的声明式开发范式的方舟框架是一套开发极简、高性能、支持跨设备的UI开发框架,提供了构建HarmoneyOS应用UI所必需的能力
声明式UI和命令式UI对比
命令式开发范式:它由开发者一步一步的告诉计算机执行一系列的操作,得到想要的结果,这一过程中起主要作用的是开发者,计算机只是帮助开发者去执行计算
声明式开发范式:直接告诉计算机它想要的结果,怎么做由预先写好的程序依据一定的算法由计算机自动推算出来
与命令式开发相比的几个优点:
- 对于系统使用方: 通过设计声明式的接口,开发者无需关心底层实现,而更多关注上层业务
- 对于系统实现方:通过声明式的接口上层使用者接口相对稳定,系统可以不断的迭代优化
- 对于整个系统:能够更系统地收集更多信息能够依据策略进行系统行为优化,提升系统效率
声明式UI和类Web式UI对比
该开发方式更接近于Web前端开发者的使用习惯,便于快速将已有地Web应用改造成方舟UI框架应用,适用于界面较简单地中小型应用或者是卡片。
声明式UI和命令式UI数据更新机制对比
命令式UI数据更新机制:以Java代码为例,需要手动更新UI数据
声明式则不需要改动整体地业务逻辑,只需抽取数据然后变更数据内容即可实现刷新
总结
基于ArkTS的声明式开发范式的核心就是 数据驱动UI页面更新
开发者只需要简单的数据变更即可实现UI页面的更新
极简的UI语法,声明式UI开发带来高效开发体验与灵活性
声明式UI是系统选用的新一代开发范式,通过数据驱动UI变化,UI逻辑分离,更直观,更高效。
关键特征:
- 类自然语言的UI结构描述
- 积木式组件组合
- 极简语法-动效
常用组件
Button
Text
Image
线性布局(Row/Column)
创建列表(List)
创建网格(Grid/GridItem)
创建轮播(Swiper)
瀑布流(WaterFlow)
其他常用组件汇总
案例:快速入门
页面结构总览
组件的使用选择
主标题和分标题可以选择Text组件来进行实现
快速入门下的运营推荐位可以使用Swiper,以实现运营推荐位的需求
在本例中可以设置Grid单行显示,则赋能套件部分可以横向滑动。
入门教程部分由List组件实现
组件介绍
Text组件用于在界面上展示一段文本信息
Swiper轮播图组件提供滑动轮播显示的能力
Grid组件为网格容器由行和列分隔的单元格所组成,其中容器内个条目对应一个GridItem组件,如果仅设置行、列、数量与占比之中的一个,网格单元格将按照设置的方向排列,超出Grid显示区域后Grid拥有可滚动的能力。
List组件可以轻松高效地显示结构化可滚动的信息,当列表项达到一定数量时,内容超过屏幕大小可以自动提供滚动能力。
构建快速入门页
准备数据
下面会用到的两个类:
class BannerClass {
id: string = '';
imageUrl: ResourceStr = '';
url: string = ''
constructor(id: string, imageUrl: ResourceStr, url: string) {
this.id = id;
this.imageUrl = imageUrl;
this.url = url;
}
}
class ArticleClass {
id: string = '';
imageSrc: ResourceStr = '';
title: string = ''
brief: string = '';
webUrl: string = '';
constructor(id: string, imageSrc: ResourceStr, title: string, brief: string, webUrl: string) {
this.id = id;
this.imageSrc = imageSrc;
this.title = title;
this.brief = brief;
this.webUrl = webUrl;
}
}
将会用到的数据源的数据
bannerList: Array<BannerClass> = [
new BannerClass('pic0', $r('app.media.banner_pic0'),
'https://developer.huawei.com/consumer/cn/training/course/video/C101718352529709527'),
new BannerClass('pic1', $r('app.media.banner_pic1'),
'https://developer.huawei.com/consumer/cn/'),
new BannerClass('pic2', $r('app.media.banner_pic2'),
'https://developer.huawei.com/consumer/cn/deveco-studio/'),
new BannerClass('pic3', $r('app.media.banner_pic3'),
'https://developer.huawei.com/consumer/cn/arkts/'),
new BannerClass('pic4', $r('app.media.banner_pic4'),
'https://developer.huawei.com/consumer/cn/arkui/'),
new BannerClass('pic5', $r('app.media.banner_pic5'),
'https://developer.huawei.com/consumer/cn/sdk')
];
tutorialList: Array<ArticleClass> = [
new ArticleClass('1', $r('app.media.tutorial_pic1'), 'Step1 环境的搭建',
'本篇教程实现了快速入门——一个用于了解和学习HarmonyOS的应用程序。',
'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
new ArticleClass('2', $r('app.media.tutorial_pic2'), 'Step2 使用Swiper构建运营广告位',
'Swiper组件提供滑动轮播显示的能力。Swiper本身是一个容器组件,当设置了多个子组件后,可以对这些子组件进行轮播显示。',
'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
new ArticleClass('3', $r('app.media.tutorial_pic3'), 'Step3 创建和组合视图',
'Item定义子组件相关特征。相关组件支持使用条件渲染、循环渲染、懒加载等方式生成子组件。',
'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
new ArticleClass('4', $r('app.media.tutorial_pic4'), 'Step4 网格和列表组建的使用',
'网格和列表组件中,当Item达到一定数量,内容超过屏幕大小时,可以自动提供滚动功能,适合用于呈现同类数据类型或数据类型集',
'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
new ArticleClass('5', $r('app.media.tutorial_pic5'), 'Step5 应用架构设计基础——MVVM模式',
'ArkUI采取MVVM = Model + View + ViewModel模式,将数据与视图绑定在一起,更新数据的时候直接更新视图。',
'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
new ArticleClass('6', $r('app.media.tutorial_pic6'), 'Step6 应用架构设计基础——三层架构',
'为了更好地适配复杂应用的开发,建议采用三层架构的方式对整个应用的功能进行模块化,实现高内聚、低耦合开发。',
'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
new ArticleClass('7', $r('app.media.tutorial_pic7'), 'Step6 ArkWeb页面适配',
'ArkWeb(方舟Web)提供了Web组件,用于在应用程序中显示Web页面内容,为开发者提供页面加载、页面交互、页面调试等能力。',
'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
new ArticleClass('8', $r('app.media.tutorial_pic8'), 'Step7 数据驱动UI更新', '数据更新的同时会直接驱动UI的改变',
'xxx'),
new ArticleClass('9', $r('app.media.tutorial_pic9'), 'Step8 设置组件导航',
'Navigation组件适用于模块内页面切换,一次开发,多端部署场景。通过组件级路由能力实现更加自然流畅的转场体验,并提供多种标题栏样式来呈现更好的标题和内容联动效果。',
'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
new ArticleClass('10', $r('app.media.tutorial_pic10'), 'Step9 原生智能:AI语音朗读',
'文本转语音服务提供将文本信息转换为语音并进行播报的能力,便于用户与设备进行互动,实现实时语音交互,文本播报。',
'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
new ArticleClass('11', $r('app.media.tutorial_pic11'), 'Step10 原生互联:分布式流转',
'流转能力打破设备界限,多设备联动,使用户应用程序可分可合、可流转,实现如邮件跨设备编辑、多设备协同健身、多屏游戏等分布式业务。',
'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
new ArticleClass('12', $r('app.media.tutorial_pic12'), 'Step11 一次开发,多端部署',
'一套代码工程,一次开发上架,多端按需部署。支撑开发者快速高效的开发支持多种终端设备形态的应用,实现对不同设备兼容的同时,提供跨设备的流转、迁移和协同的分布式体验。',
'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
];
tutorialList: Array<ArticleClass> = [
new ArticleClass('1', $r('app.media.tutorial_pic1'), 'Step1 环境的搭建',
'本篇教程实现了快速入门——一个用于了解和学习HarmonyOS的应用程序。',
'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
new ArticleClass('2', $r('app.media.tutorial_pic2'), 'Step2 使用Swiper构建运营广告位',
'Swiper组件提供滑动轮播显示的能力。Swiper本身是一个容器组件,当设置了多个子组件后,可以对这些子组件进行轮播显示。',
'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
new ArticleClass('3', $r('app.media.tutorial_pic3'), 'Step3 创建和组合视图',
'Item定义子组件相关特征。相关组件支持使用条件渲染、循环渲染、懒加载等方式生成子组件。',
'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
new ArticleClass('4', $r('app.media.tutorial_pic4'), 'Step4 网格和列表组建的使用',
'网格和列表组件中,当Item达到一定数量,内容超过屏幕大小时,可以自动提供滚动功能,适合用于呈现同类数据类型或数据类型集',
'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
new ArticleClass('5', $r('app.media.tutorial_pic5'), 'Step5 应用架构设计基础——MVVM模式',
'ArkUI采取MVVM = Model + View + ViewModel模式,将数据与视图绑定在一起,更新数据的时候直接更新视图。',
'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
new ArticleClass('6', $r('app.media.tutorial_pic6'), 'Step6 应用架构设计基础——三层架构',
'为了更好地适配复杂应用的开发,建议采用三层架构的方式对整个应用的功能进行模块化,实现高内聚、低耦合开发。',
'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
new ArticleClass('7', $r('app.media.tutorial_pic7'), 'Step6 ArkWeb页面适配',
'ArkWeb(方舟Web)提供了Web组件,用于在应用程序中显示Web页面内容,为开发者提供页面加载、页面交互、页面调试等能力。',
'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
new ArticleClass('8', $r('app.media.tutorial_pic8'), 'Step7 数据驱动UI更新', '数据更新的同时会直接驱动UI的改变',
'xxx'),
new ArticleClass('9', $r('app.media.tutorial_pic9'), 'Step8 设置组件导航',
'Navigation组件适用于模块内页面切换,一次开发,多端部署场景。通过组件级路由能力实现更加自然流畅的转场体验,并提供多种标题栏样式来呈现更好的标题和内容联动效果。',
'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
new ArticleClass('10', $r('app.media.tutorial_pic10'), 'Step9 原生智能:AI语音朗读',
'文本转语音服务提供将文本信息转换为语音并进行播报的能力,便于用户与设备进行互动,实现实时语音交互,文本播报。',
'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
new ArticleClass('11', $r('app.media.tutorial_pic11'), 'Step10 原生互联:分布式流转',
'流转能力打破设备界限,多设备联动,使用户应用程序可分可合、可流转,实现如邮件跨设备编辑、多设备协同健身、多屏游戏等分布式业务。',
'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
new ArticleClass('12', $r('app.media.tutorial_pic12'), 'Step11 一次开发,多端部署',
'一套代码工程,一次开发上架,多端按需部署。支撑开发者快速高效的开发支持多种终端设备形态的应用,实现对不同设备兼容的同时,提供跨设备的流转、迁移和协同的分布式体验。',
'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
];
💡 图片资源可以到到官方给出的案例中去下载源码<HarmonyOS第一课>从简单的页面开始-华为开发者学堂 (huawei.com)
设置快速入门标题
// 设置文本内容
Text('快速入门')
//分别设置字体、字体大小、字体粗细、文本的行高
.fontFamily('HarmonyHeiTi-Bold')
.fontSize(25)
.fontWeight(FontWeight.Bold)
.lineHeight(33)
// 设置文本段落在水平方向的对齐方式
.textAlign(TextAlign.Start)
.padding({ left: 16 })
.margin({ top: 20 })
.width('100%')
使用循环渲染:ForEach
ForEach简介
通过ForEach从数组中获取数据,并为每个数据项创建相应的组件,可减少重复代码
ForrEach(
arr:Array,
itemGenerator:(item:Array,index?:number)=>void,
keyGenerator?:(item:Array,index?:number):string => string
)
ForEach包含的三个参数:
参数1:数据源,为Array类型的数组。
参数2:itemGenerator为子组件生成函数,为数组中的每个元素创建对应的组件。
参数3:keyGenerator为数组项唯一键值生成函数,为数据源arr的每个数组项生成唯一且持久的键值。函数返回值为开发者自定义的键值生成规则
设置轮播图
@Component
struct Banner {
// 准备轮播的数据
@State bannerList: Array<BannerClass> = [......];
// 创建Swiper控制器
private swiperController: SwiperController = new SwiperController();
build() {
Swiper(this.swiperController) {
// 循环渲染
ForEach(this.bannerList, (item: BannerClass, index: number) => {
// 将Image组件作为Item
Image(item.imageUrl)
.objectFit(ImageFit.Contain)
.width('100%')
.padding({ top: 11, left: 16, right: 16 })
.borderRadius(16)
}, (item: BannerClass, index: number) => item.id)
}
// 设置自动播放和循环播放
.autoPlay(true)
.loop(true)
}
设置网格
@Component
struct EnablementView {
// 准备数据
@State enablementList: Array<ArticleClass> = [...];
build() {
Column() {
Text('赋能套件')
.fontColor('#182431')
.fontSize(16)
.fontWeight(500)
.fontFamily('HarmonyHeiTi-medium')
.textAlign(TextAlign.Start)
.padding({left: 16})
.margin({bottom: 8.5})
// 设置网格容器
Grid() {
// 对GridItem循环
ForEach(this.enablementList,(item: ArticleClass)=>{
GridItem(){
EnablementItem({enablementItem: item})
}
},(item: ArticleClass)=> item.id)
}
.rowsTemplate('1fr')
.columnsGap(8)
.scrollBar(BarState.Off)
.height(169)
.padding({top: 2, left: 16, right: 16})
}
.margin({top: 18})
.alignItems(HorizontalAlign.Start)
}
}
@Component
struct EnablementItem {
@Prop enablementItem: ArticleClass;
build() {
// 设置Column布局
Column(){
// 设置配图
Image(this.enablementItem.imageSrc)
.width('100%')
.objectFit(ImageFit.Cover)
.height(96)
.borderRadius({
topLeft:16,
topRight:16
})
// 设置标题
Text(this.enablementItem.title)
.height(19)
.width('100%')
.fontSize(14)
.textAlign(TextAlign.Start)
.textOverflow({overflow: TextOverflow.Ellipsis})
.maxLines(1)
.fontWeight(400)
.padding({left: 12, right: 12})
.margin({top: 8})
// 设置简介
Text(this.enablementItem.brief)
.height(32)
.width('100%')
.fontSize(12)
.textAlign(TextAlign.Start)
.textOverflow({overflow: TextOverflow.Ellipsis})
.maxLines(2)
.fontWeight(400)
.fontColor('rgba(0,0,0,0.6)')
.padding({left: 12, right: 12})
.margin({top: 2})
}
.width(160)
.height(169)
.backgroundColor(Color.White)
}
}
设置列表
@Component
struct TutorialView {
@State message: string = "入门教程"
// 准备数据
@State tutorialList: Array<ArticleClass> = [......];
build() {
Column() {
Text(this.message)
.fontSize(16)
.fontWeight(500)
.fontFamily('HarmonyHeiTi-medium')
.textAlign(TextAlign.Start)
.padding({left: 16})
.width('100%')
.margin({bottom: 8.5})
// 设置列表容器
List({space: 12}) {
// 进行数据源循环
ForEach(this.tutorialList,(item: ArticleClass)=>{
ListItem() {
TutorialItem({ tutorialItem: item })
}
}, (item: ArticleClass) => item.id)
}
.width('auto')
.height('auto')
}
}
}
@Component
struct TutorialItem {
// 接收来着父组件的数据
@Prop tutorialItem: ArticleClass;
build() {
// 用Row包裹整个视图
Row() {
// 设置Column布局
Column(){
// 包裹两个Text组件
Text(this.tutorialItem.title)
.height(19)
.width('100%')
.fontSize(14)
.textAlign(TextAlign.Start)
.textOverflow({overflow: TextOverflow.Ellipsis})
.maxLines(1)
.fontWeight(400)
.margin({top: 4})
Text(this.tutorialItem.brief)
.height(32)
.width('100%')
.fontSize(12)
.textAlign(TextAlign.Start)
.textOverflow({overflow: TextOverflow.Ellipsis})
.maxLines(2)
.fontWeight(400)
.fontColor('rgba(0,0,0,0.6)')
.margin({top: 5})
}
.height('100%')
.layoutWeight(1)
.alignItems(HorizontalAlign.Start)
.margin({right: 12})
// 设置Image组件
Image(this.tutorialItem.imageSrc)
.height(64)
.width(108)
.objectFit(ImageFit.Cover)
.borderRadius(16)
}
.width('100%')
.height(88)
.borderRadius(16)
.backgroundColor(Color.White)
.padding(12)
.alignItems(VerticalAlign.Top)
}
}
组合完整页面
@Entry
@Component
struct Index {
@State message: string = '快速入门';
build() {
Column() {
Text(this.message)
.fontSize(24)
.fontWeight(700)
.width('100%')
.textAlign(TextAlign.Start)
.padding({ left: 16 })
.fontFamily('HarmonyHeiTi-Bold')
.lineHeight(33)
Scroll() {
Column() {
// 运营推荐位
Banner()
//赋能套件
EnablementView()
//入门教程
TutorialView()
}
}
.layoutWeight(1)
.scrollBar(BarState.Off)
.align(Alignment.TopStart)
}
.width('100%')
.height('100%')
.backgroundColor('#F1F3F5')
}
}
总结与回顾
- 使用Text、Image等基本组件
- 使用ForEach循环渲染组件
- 使用Swiper组件构建轮播图
- 使用Grid组件构建网格布局
- 使用List组件构建列表布局