高端网站建设哪里好,荆轲网络做网站,做产品的淘宝客网站,wordpress 博客信息一、ArkUI框架简介
ArkUI开发框架是方舟开发框架的简称#xff0c;它是一套构建 HarmonyOS / OpenHarmony 应用界面的声明式UI开发框架#xff0c;它使用极简的UI信息语法、丰富的UI组件以及实时界面语言工具#xff0c;帮助开发者提升应用界面开发效率 30%#xff0c;开发…一、ArkUI框架简介
ArkUI开发框架是方舟开发框架的简称它是一套构建 HarmonyOS / OpenHarmony 应用界面的声明式UI开发框架它使用极简的UI信息语法、丰富的UI组件以及实时界面语言工具帮助开发者提升应用界面开发效率 30%开发者只需要使用一套 TS / JS API就能在多个 HarmonyOS / OpenHarmony 设备上提供既丰富又流畅的用户界面体验。
1.1.UI开发框架
什么是UI开发框架 UI即用户界面主要包含视觉比如文字、图像、动画等可以看到的内容以及交互比如点击按钮、滑动列表、放缩图片等用户操作。 UI框架是为软件应用开发者提供开发UI的基础设施主要包括UI控件按钮/列表等、视图布局摆放/排列相应的UI控件、动画机制动画设计以及效果呈现、交互事件处理点击/滑动等以及相应的编程语言和编程模型等。
UI编程框架提供了开发以及运行UI界面所需要的框架能力如下图所示 说明
开发模型对开发者提供开发范式、UI控件、布局、动效、交互、编程语言等。体现出来的是开发时候的难以程度和开发效率。运行框架UI界面渲染及交互的基础能力框架包括相应的布局引擎、控件机制、动画引擎、事件机制、渲染管线等并结合语言虚拟机和图形引擎将开发者的程序运行在具体系统平台上。体现出来的是应用运行的性能体验。平台适配承载框架的具体操作系统或平台适配层。
1.2.ArkUI框架的演进
ArkUI开发框架综合考虑了UI渲染、语言和运行效率围绕着极简开发、高性能、跨设备跨平台进一步演进。下图是ArkUI整体架构的演进 上图中左侧是 2020 年 HarmonyOS 发布的JS UI框架的架构示意图主要支持类Web的前端开发范式通过DSLdomain-specific language领域特定语言转换层跨语言对接到声明式UI后端引擎并结合JS引擎完成整体UI渲染。右侧是ArkUI开发框架主要有以下几个变化
引入了新一代的声明式UI开发范式实现极简的UI描述语法。设计了统一的前后端扁平化渲染机制进一步提升UI渲染的性能并降低内存消耗。深度结合 ArkCompiler 方舟编译器和 ArkRuntime 方舟运行时提升语言的执行性能和跨语言通信能力。在工具方面针对新一代的声明式UI开发范式构建了新的编译工具链和预览引擎提供了所见即所得的实时预览机制。
另外在ArkUI开发框架中类Web范式会继续保留即类Web范式和新一代的声明式UI范式都可以支持可以各自独立使用但不能混用。
1.3.ArkUI的关键特性
①.极简的UI信息语法
ArkUI开发框架采用基于 TypeScript 扩展的极简的声明式UI描述界面语法提供了类自然语言的UI描述和组合开发者只需用几行简单直观的声明式代码即可完成界面功能。
②.丰富的内置UI组件
ArkUI开发框架内置了丰富而精美的多态组件可满足大部分应用界面开发的需求开发者可以轻松地向几乎任何UI控件添加动画并选择一系列框架内置的动画能力可为用户带来平滑而自然的体验。其中多态是指UI描述是统一的UI呈现在不同类型设备上会有所不同。比如 Button 组件在手机和手表会有不同的样式和交互方式。
③.多维度的状态管理机制
ArkUI开发框架为开发者提供了跨设备数据绑定功能和多维度的状态管理机制组件内/组件间/全局/分布式数据驱动UI变更支持灵活的数据驱动的UI变更帮助开发者节省70%代码完成跨端界面应用开发。
④.支持多设备开发
ArkUI开发框架除了提供UI开发套件外还围绕着多设备开发提供了多维度的解决方案进一步简化开发
基础开发能力包括基础的分层参数配置比如色彩、字号、圆角、间距等栅格系统原子化布局能力比如拉伸、折行、隐藏等。零部件组件层包括多态控件统一交互能力以及在此基础上的组件组合。面向典型场景提供分类的页面组合模板以及示例代码。
⑤.原生性能体验
ArkUI开发框架内置了许多核心的UI控件和动效如图片、列表、网格、属性动画、转场动画等加持自研的 ArkCompiler 方舟编译器和 ArkRuntime 方舟运行时深度优化这些都可以在 HarmonyOS / OpenHarmony 设备上达到移动原生应用一样的性能体验。
⑥.实时预览机制
ArkUI开发框架支持实时界面预览特性可帮助开发快速的所见即所得的开发和调测界面无需连接真机设备就可以显示应用界面在任何 HarmonyOS / OpenHarmony 设备上的UI效果预览的关键特性主要包括
一致性渲染和目标设备一致的UI呈现效果。实时性预览改动相应的代码实时呈现出相应UI效果。另外代码能够和UI双向联动代码改动的同时UI也实时变更UI改动的同时代码也相应地变更。多维度预览支持页面级预览、组件级预览、多设备预览。
1.4.声明式UI开发范式的基本组成
1.4.1.创建项目
创建项目说明 1.4.2.基本组成说明
下面我们以一个具体的示例来说明新一代声明式UI开发范式的基本组成。如下图所示的代码示例UI界面会显示一个 数字 按钮。当用户点击 按钮时每点击一次会加 1 。 上面的案例构成说明如下
装饰器用来装饰类、结构体、方法以及变量赋予其特殊的含义上面 Entry 、 Component 、 State 都是装饰器。 Component 表示这是个自定义组件Entry 则表示这是个页面入口组件也就是根组件State 表示组件中的状态变量这个状态变化会引起UI变更。 自定义组件可复用的UI单元可组合其它组件如上述被 Component 装饰的 struct Index 。UI描述声明式的方式来描述UI的结构如上述 build() 方法内部的代码块。内置组件框架中默认内置的基础组件可直接被开发者调用比如上面案例的Button。事件方法用于添加组件对事件的响应逻辑统一通过事件方法进行设置如跟随在Button后面的onClick()方法。属性方法用于组件属性的配置统一通过属性方法进行设置如fontSize()、width()、height()、size()等可通过链式调用的方式设置多项属性。
上述示例中用 State 装饰的变量 times 包含了一个基础的状态管理机制即 times 的值的变化会引起相应的UI组件Button的变化ArkUI开发框架还提供多维度的状态管理机制和UI相关联的数据不仅仅在组件内使用还可以在不同组件层级间传递比如父子组件之间爷孙组件之间也可以是全局范围内的传递还可以是跨设备传递。
二、资源管理
应用开发过程中经常需要用到颜色、字体、间距、图片等资源在不同的设备或配置中这些资源的值可能不同。 应用资源借助资源文件能力开发者在应用中自定义资源自行管理这些资源在不同的设备或配置中的表现。 系统资源开发者直接使用系统预置的资源定义即分层参数同一资源ID在设备类型、深浅色等不同配置下有不同的取值。
2.1.资源分类
移动端应用开发常用到的资源比如图片、音视频和字符串等在OpenHarmony 规定把这些应用的资源文件统一放在 resources 目录下的各子目录中便于开发者使用和维护 resoures 目录包括两大类
一类为 base 目录与限定词目录另一类为 rawfile 目录
新建 OpenHarmony 应用默认生成的资源目录如下所示 base 目录与限定词目录下面可以创建资源组目录包括 element 、 media 、 profile 用于存放特定类型的资源文件各资源目录说明如下图所示 2.2.资源访问
OpenHarmony 应用资源分为两类一类是应用资源另一类是系统资源它们的资源访问方式如下
1访问应用资源
base 目录下的资源文件会被编译成二进制文件并且给这些资源赋予唯一的 ID 使用相应资源的时候通过资源访问符 $r(‘app.type.name’) 的形式
app 代表是应用内 resources 目录中定义的资源type 表示资源类型可取值的有有 color 、 float 、 string 、 string 、 media 等name 表示资源的文件名字。
例如string.json 中新加 name 为 text_string 的字符串则访问该字符串资源为 $r(‘app.string.text_string’)
在base 目录的子目录element下新建 float.json string.json 、color.json文件分别存放浮点型、字体和颜色资源内容如下图所示 需要注意的是因为国际化的问题
string.json中配置的内容需要在在zh_CN和en_US的string.json中添加相同的内容就会根据本地的语言环境进行显示
在media准备一张图片后面作为文本框的背景图使用 创建ResourceDemo.ets文件,应用上面的内容如下
Entry
Component
struct ResourceDemo{build(){Column(){Text($r(app.string.hi_string)) //访问字符串资源.size({width:300, height:120}) //设置尺寸.fontSize($r(app.float.text_size))//访问字体大小.fontColor($r(app.color.text_color))//访问字体颜色.backgroundImage($r(app.media.Sns), ImageRepeat.XY) //设置背景图片,ImageRepeat.XY则是图片太小时候选择某个坐标位置的颜色填充}.width(100%) //表示将组件的宽度设置为父容器的100%.height(100%) //表示将组件的高度设置为父容器的100%.padding(10)//表示设置组件的内边距为10个单位。}
}预览效果如下 2访问系统资源
除了自定义资源开发者也可以使用系统中预定义的资源统一应用的视觉风格。可以查看应用UX设计中关于资源的介绍获取支持的系统资源ID及其在不同配置下的取值。在开发过程中分层参数的用法与资源限定词基本一致。对于系统资源可以通过“$r(‘sys.type.resource_id’)”的形式引用。其中sys为系统资源type为资源类型取值包括“color”、“float”、“string”、“media”resource_id为资源id。说明
仅声明式开发范式支持使用系统资源。对于系统预置应用建议使用系统资源对于三方应用可以根据需要选择使用系统资源或自定义应用资源。
案例创建 ResourceDemo2.ets内容如下
Entry
Component
struct ResourceDemo2{build(){Column(){Text(HelloWorld).fontColor($r(sys.color.ohos_id_color_emphasize)) // 设置字体颜色.fontSize($r(sys.float.ohos_id_text_size_headline5)) // 设置字体大小.fontFamily($r(sys.string.ohos_id_text_font_family_medium)) // 设置字体.backgroundColor($r(sys.color.ohos_id_color_palette_aux1)) // 设置背景颜色Image($r(sys.media.ohos_app_icon)).border({color: $r(sys.color.ohos_id_color_palette_aux11), // 设置边框颜色为辅助色11radius: $r(sys.float.ohos_id_corner_radius_button), // 设置边框圆角半径为按钮圆角半径width: 2 // 设置边框宽度为2}).margin({top: $r(sys.float.ohos_id_elements_margin_horizontal_m), // 设置上边距为水平中等间距bottom: $r(sys.float.ohos_id_elements_margin_horizontal_l) // 设置下边距为水平大间距}).height(200) // 设置高度为200.width(300) // 设置宽度为300}.width(100%).height(100%).padding(10)}
}预览结果如下 2.3.像素单位
1像素单位说明 ArkUI开发框架提供了 4 种像素单位供开发者使用分别是 px 、 vp 、 fp 和 lpx 框架采用vp为基准数据单位。它们之间的区别如下表所示 2像素单位转换 提供其他单位与px单位互相转换的方法。 案例如下
Entry
Component
struct Example {build() {Column() {/**Flex({ wrap: FlexWrap.Wrap })是一个Flex布局的设置*其中wrap: FlexWrap.Wrap表示设置Flex容器的子元素在主轴方向上超出容器时是否换行。*在这里FlexWrap.Wrap表示子元素会自动换行以适应容器的尺寸。* 这样设置可以确保在容器尺寸不足以容纳所有子元素时子元素会自动换行而不会超出容器范围。*/Flex({ wrap: FlexWrap.Wrap }) {// 默认不写单位就是是vpColumn() {Text(width(220)).width(220) // 设置宽度为220vp.height(40) // 设置高度为40vp.backgroundColor(#00BFC9) // 设置背景颜色为#00BFC9.fontSize(12vp) // 设置字体大小为12vp}.margin(5) // 设置外边距为5vp// 宽度指定成pxColumn() {Text(width(220px)).width(220px) // 设置宽度为220px.height(40) // 设置高度为40vp.backgroundColor(#007900) // 设置背景颜色为#007900.textAlign(TextAlign.Center) // 设置文本对齐方式为居中.fontColor(Color.White) // 设置字体颜色为白色}.margin(5) // 设置外边距为5vp// 宽度指定成vpColumn() {Text(width(220vp)).width(220vp) // 设置宽度为220vp.height(40) // 设置高度为40vp.backgroundColor(#FF9800) // 设置背景颜色为#FF9800.textAlign(TextAlign.Center) // 设置文本对齐方式为居中.fontColor(Color.White) // 设置字体颜色为白色.fontSize(12vp) // 设置字体大小为12vp}.margin(5) // 设置外边距为5vp// 宽度指定成vplpxColumn() {Text(width(220lpx) designWidth:720).width(220lpx) // 设置宽度为220lpx.height(40) // 设置高度为40vp.backgroundColor(#634794) // 设置背景颜色为#634794.textAlign(TextAlign.Center) // 设置文本对齐方式为居中.fontColor(Color.White) // 设置字体颜色为白色.fontSize(12vp) // 设置字体大小为12vp}.margin(5) // 设置外边距为5vp// 将vp单位的数值转换为以px为单位的数值Column() {Text(width(vp2px(220) px)).width(vp2px(220) px) // 将220vp转换为px单位的数值然后设置宽度.height(40) // 设置高度为40vp.backgroundColor(#3F56EA) // 设置背景颜色为#3F56EA.textAlign(TextAlign.Center) // 设置文本对齐方式为居中.fontColor(Color.White) // 设置字体颜色为白色.fontSize(12vp) // 设置字体大小为12vp}.margin(5) // 设置外边距为5vp// fontSize(12fp)设置成fpColumn() {Text(fontSize(12fp)).width(220) // 设置宽度为220vp.height(40) // 设置高度为40vp.backgroundColor(#A14A5C) // 设置背景颜色为#A14A5C.textAlign(TextAlign.Center) // 设置文本对齐方式为居中.fontColor(Color.White) // 设置字体颜色为白色.fontSize(12fp) // 设置字体大小为12fp}.margin(5) // 设置外边距为5vp// 将px单位的数值转换为以vp为单位的数值。Column() {Text(width(px2vp(220))).width(px2vp(220)) // 将220px转换为vp单位的数值然后设置宽度.height(40) // 设置高度为40vp.backgroundColor(#E40078) // 设置背景颜色为#E40078.textAlign(TextAlign.Center) // 设置文本对齐方式为居中.fontColor(Color.White) // 设置字体颜色为白色.fontSize(12fp) // 设置字体大小为12fp}.margin(5) // 设置外边距为5vp}.width(100%) // 设置宽度为100%}}
}2.4.资源管理器
ArkUI开发框架在 ohos.resourceManager 模块里提供了资源管理器 ResourceManager它可以访问不同的资源比如获取获取字符串资源获取设备配置信息等等参考地址https://developer.harmonyos.com/cn/docs/documentation/doc-references-V3/js-apis-resource-manager-0000001478181625-V3resourceManager 模块 API 如下
declare namespace resourceManager {// 省略部分代码export interface ResourceManager {// 获取字符串资源getString(resId: number, callback: AsyncCallbackstring): void;// 获取字符串数组资源getStringArray(resId: number, callback: AsyncCallbackArraystring): void;// 获取媒体资源getMedia(resId: number, callback: AsyncCallbackUint8Array): void;// 获取设备信息比如当前屏幕密度设备类型是手机还是平板等getDeviceCapability(callback: AsyncCallbackDeviceCapability): void;// 获取配置信息比如当前屏幕方向密度当前设备语言getConfiguration(callback: AsyncCallbackConfiguration): void;// 释放ResourceManager资源release();}
}
export default resourceManager;使用 ResourceManager 之前先调用 getContext(this) 方法获取当前组件的 Context该 Conetxt 内部定义了一个 ResourceManager 的属性因此可以直接使用 ResourceManager 的各种 getXXX() 方法获取对应资源 ResourceManager应用流程如下
1引入 resourceManager
import resourceManager from ohos.resourceManager;2获取 ResourceManager
aboutToAppear() {// 获取ResourceManagerlet manager getContext(this).resourceManager;
}3使用 ResourceManager
manager.getString(0x1000001, (innerError, data) {if(data) {// 获取资源成功} else {console.log(error: JSON.stringify(innerError))}
})4释放 ResourceManager
this.manager.release();完整案例如下
import resourceManager from ohos.resourceManager; // 导入资源管理器模块Entry
Component
struct Example02{State text_string: string ; // 定义文本字符串状态State capability: string ; // 定义设备能力状态State configuration: string ; // 定义设备配置状态private resManager: resourceManager.ResourceManager; // 声明资源管理器build(){Column({space:10}){ // 创建一个垂直布局的Column组件设置子元素间距为10Text(this.text_string) // 显示文本字符串资源.size({width:300, height:120}) // 设置尺寸为宽300高120.fontSize($r(app.float.text_size)) // 使用资源管理器获取字体大小.fontColor($r(app.color.text_color)) // 使用资源管理器获取字体颜色.backgroundImage($r(app.media.Sns)) // 使用资源管理器设置背景图片Text(this.capability) // 显示设备能力信息.fontSize(20) // 设置字体大小为20Text(this.configuration) // 显示设备配置信息.fontSize(20) // 设置字体大小为20}.width(100%) // 设置宽度为100%.height(100%) // 设置高度为100%.padding(10) // 设置内边距为10}aboutToAppear(){this.resManager getContext(this).resourceManager; // 获取上下文中的资源管理器this.resManager.getStringValue(0x1000001,(innerError,data){ // 获取字符串资源值if(data){this.text_string data; // 将获取到的字符串资源值赋给text_string状态}else{console.log(error:JSON.stringify(innerError)); // 打印错误信息}this.resManager.getDeviceCapability((innerError, deviceCapability){ // 获取设备能力信息if(deviceCapability){this.capability JSON.stringify(deviceCapability); // 将设备能力信息转换为JSON字符串并赋给capability状态}})this.resManager.getConfiguration((innerError, configuration){ // 获取设备配置信息if(configuration){this.configuration JSON.stringify(configuration); // 将设备配置信息转换为JSON字符串并赋给configuration状态}})})}aboutToDisappear(){this.resManager?.release(); // 释放资源管理器资源}
}注意渲染出来的 mock string 是因为在预览器上暂时不支持 ResourceManager 的用法在实际设备上可以执行。
三、渲染控制语法
ArkTS也提供了渲染控制的能力。条件渲染可根据应用的不同状态渲染对应状态下的UI内容。循环渲染可从数据源中迭代获取数据并在每次迭代过程中创建相应的组件。参考网址
https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ets-rendering-control-0000001149698611
3.1.if/else条件渲染
使用 if/else 进行条件渲染需要注意以下情况
if 条件语句可以使用状态变量。使用 if 可以使子组件的渲染依赖条件语句。必须在容器组件内使用。某些容器组件限制子组件的类型或数量。将if放置在这些组件内时这些限制将应用于 if 和 else 语句内创建的组件。例如Grid 组件的子组件仅支持 GridItem 组件在 Grid 组件内使用条件渲染时则 if 条件语句内仅允许使用 GridItem 组件。
案例如下
Entry
Component
struct ComponentTest {State showImage: boolean false; // 定义showImage状态默认为falsebuild() {// 纵向布局元素垂直方向间距。Column({space:10}){ // 创建一个垂直布局的Column组件设置子元素间距为10// 如果showImage为true则显示图片否则显示Loading .....if(this.showImage){Image($r(app.media.Sns)) // 显示图片使用资源管理器获取图片资源.width(160) // 设置宽度为160.height(60) // 设置高度为60.backgroundColor(Color.Pink) // 设置背景颜色为粉色}else {Text(Loading .....).fontSize(23) // 设置字体大小为23.fontColor(#FFFFF0) //设置字体颜色为象牙色.width(160) // 设置宽度为160.height(60) // 设置高度为60.backgroundColor(Color.Pink) // 设置背景颜色为粉色.textAlign(TextAlign.Center) // 设置文本居中对齐}Button(this.showImage?Image Loaded:Load Image) // 按钮内容根据showImage状态动态显示.size({width:160,height:40}) // 设置按钮的宽和高.backgroundColor(this.showImage?#3F56EA:#9C554B) // 根据showImage状态设置按钮背景色.onClick((){ // 点击事件处理this.showImage true; // 点击后设置showImage值为true显示图片})}.width(100%) // 设置宽度为100%.height(100%) // 设置高度为100%.padding(10) // 设置内边距为10}
}预览效果如下 3.2.ForEach循环渲染
ArkUI开发框架提供循环渲染ForEach组件来迭代数组并为每个数组项创建相应的组件。ForEach 定义如下
3.2.ForEach循环渲染
ArkUI开发框架提供循环渲染ForEach组件来迭代数组并为每个数组项创建相应的组件。ForEach 定义如下
interface ForEach {(arr: Arrayany, itemGenerator: (item: any, index?: number) void,keyGenerator?: (item: any, index?: number) string): ForEach;
}说明
arr必须是数组允许空数组空数组场景下不会创建子组件。itemGenerator子组件生成函数为给定数组项生成一个或多个子组件。keyGenerator匿名参数用于给定数组项生成唯一且稳定的键值。
案例如下
Entry
Component
struct ComponentTest02 {//准备源数据private textArray:string[] [一,二,三,四,五] // 定义一个包含字符串的数组作为源数据build() {Column({space:10}){ // 创建一个垂直布局的Column组件设置子元素间距为10ForEach(this.textArray,(item:string,index?:number){ // 遍历textArray数组Text(标题:${item}) // 显示带有标题前缀的文本.fontSize(20) // 设置字体大小为20.backgroundColor(#00B377) // 设置背景颜色为绿色.margin({top:10}) // 设置上边距为10.fontColor(#FFFFF0) // 设置字体颜色为白色})}.width(100%) // 设置宽度为100%.height(100%) // 设置高度为100%.padding(10) // 设置内边距为10}
}预览后效果如下 3.3.数据懒加载LazyForEach循环渲染
ArkUI开发框架通过数据懒加载LazyForEach从提供的数据源中按需迭代数据并在每次迭代过程中创建相应的组件。
1LazyForEach 定义如下
// LazyForEach定义
interface LazyForEach {(dataSource: IDataSource, itemGenerator: (item: any, index?: number) void,keyGenerator?: (item: any, index?: number) string): LazyForEach;
}// IDataSource定义
export declare interface IDataSource {totalCount(): number;getData(index: number): any;registerDataChangeListener(listener: DataChangeListener): void;unregisterDataChangeListener(listener: DataChangeListener): void;
}// DataChangeListener定义
export declare interface DataChangeListener {onDataReloaded(): void;onDataAdded(index: number): void;onDataMoved(from: number, to: number): void;onDataDeleted(index:number): void;onDataChanged(index:number): void;
}说明如下
itemGenerator子组件生成函数为给定数组项生成一个或多个子组件。keyGenerator匿名参数用于给定数组项生成唯一且稳定的键值。dataSource实现 IDataSource 接口的对象需要开发者实现相关接口。
2IDataSource 定义如下
export declare interface IDataSource {totalCount(): number;getData(index: number): any;registerDataChangeListener(listener: DataChangeListener): void;unregisterDataChangeListener(listener: DataChangeListener): void;
}说明如下
totalCount获取数据总数。getData获取索引对应的数据。registerDataChangeListener注册改变数据的监听器。unregisterDataChangeListener注销改变数据的监听器。
3DataChangeListener 定义如下
export declare interface DataChangeListener {onDataReloaded(): void;onDataAdded(index: number): void;onDataMoved(from: number, to: number): void;onDataDeleted(index:number): void;onDataChanged(index:number): void;
}说明如下
onDataReloadeditem重新加载数据时的回调。onDataAddeditem新添加数据时的回调。onDataMoveditem数据移动时的回调。onDataDeleteditem数据删除时的回调。onDataChangeditem数据变化时的回调。
案例如下
//##########################构造数据################################
//定义student
class Student{public sid: number; // 学生IDpublic name: string; // 学生姓名public age: number; // 学生年龄public address: string; // 学生地址public avatar: string; // 学生头像//构造方法constructor(sid: number, name: string, age: number, address: string, avatar: string) {this.sid sid; // 初始化学生IDthis.name name; // 初始化学生姓名this.age age; // 初始化学生年龄this.address address; // 初始化学生地址this.avatar avatar; // 初始化学生头像}
}// 定义一个抽象类 BaseDataSource使用泛型 T实现接口 IDataSource
abstract class BaseDataSourceT implements IDataSource {private dataSource: T[] new Array(); // 数据源使用泛型数组// 构造方法接收一个泛型数组作为参数用于初始化数据源constructor(dataList: T[]) {this.dataSource dataList; // 初始化数据源}// 返回数据源的长度totalCount(): number {return this.dataSource null ? 0 : this.dataSource.length;}// 获取指定索引的数据如果索引合法则返回数据否则返回 nullgetData(index: number): T | null {return index 0 index this.totalCount() ? this.dataSource[index] : null;}// 注册数据变化监听器这里的方法体为空需要在子类中实现具体逻辑registerDataChangeListener(listener: DataChangeListener) {}// 取消注册数据监听器这里的方法体为空需要在子类中实现具体逻辑unregisterDataChangeListener() {}
}// 继承 BaseDataSource 类指定泛型为 Student 类型
class StudentDataSource extends BaseDataSourceStudent {constructor(students: Student[]) {super(students); // 调用父类构造函数进行初始化}
}//产生数据
function mock():Student[]{let students [];for (let i 1; i 21; i) {//模拟学生数据students[i] new Student(i,student:i, i10, addressi, app.media.Sns);}return students;
}Entry
Component
struct ComponentTest03 {// mock数据private student: Student[] mock(); // 模拟学生数据// 创建dataSourceprivate dataSource: StudentDataSource new StudentDataSource(this.student); // 创建学生数据源build() {Column({ space: 10 }) { // 创建一个垂直布局的列设置间距为10List() { // 创建一个列表LazyForEach(this.dataSource, (item: Student) { // 使用自定义dataSource进行懒加载ListItem() { // 创建列表项Row() { // 创建一个水平布局的行Image($r(app.media.Sns)) // 显示学生头像.height(100%) // 设置高度为100%.width(80) // 设置宽度为80Column() { // 创建一个垂直布局的列Text(this.getName(item)) // 调用getName方法验证懒加载.fontSize(20) // 设置字体大小为20Text(address: item.address) // 显示学生地址.fontSize(17) // 设置字体大小为17}.margin({ left: 5 }) // 设置左边距为5.alignItems(HorizontalAlign.Start) // 设置子元素水平方向对齐方式为起始位置.layoutWeight(1) // 设置布局权重为1}.width(100%) // 设置宽度为100%.height(100%) // 设置高度为100%}.width(100%) // 设置宽度为100%.height(60) // 设置高度为60})}.divider({ // 设置列表的分隔线样式strokeWidth: 3, // 分隔线宽度为3color: Color.Gray // 分隔线颜色为灰色}).width(90%) // 设置宽度为90%.height(160) // 设置高度为160.backgroundColor(Color.Pink) // 设置背景颜色为粉色}.width(100%) // 设置宽度为100%.height(100%) // 设置高度为100%.padding(10) // 设置内边距为10}getName(item: Student): string {console.log(index: item.sid); // 打印学生索引日志return index item.sid , item.name; // 返回学生索引和姓名}
}执行后效果如下 输出的日志如下 说明
LazyForEach必须在容器组件内使用目前仅有List、Grid以及Swiper组件支持数据懒加载即只加载可视部分以及其前后少量数据用于缓冲避免过多的占用资源其他组件仍然是一次性加载所有的数据。LazyForEach在每次迭代中必须创建且只允许创建一个子组件。生成的子组件必须是允许包含在LazyForEach父容器组件中的子组件。允许LazyForEach包含在if/else条件渲染语句中但不* 允许LazyForEach中出现if/else条件渲染语句。为了高性能渲染通过DataChangeListener对象的onDataChange方法来更新UI时仅当itemGenerator中创建的子组件内使用了状态变量时才会触发组件刷新。itemGenerator函数的调用顺序不一定和数据源中的数据项相同在开发过程中不要假设itemGenerator和keyGenerator函数是否执行及其执行顺序。例如以下示例可能无法正常工作
LazyForEach(dataSource, item Text(${item.i}. item.data.label)),item item.data.id.toString())为了能让大家更好的学习鸿蒙 (OpenHarmony) 开发技术这边特意整理了《鸿蒙 (OpenHarmony)开发学习手册》共计890页希望对大家有所帮助https://qr21.cn/FV7h05
《鸿蒙 (OpenHarmony)开发学习手册》
入门必看https://qr21.cn/FV7h05
应用开发导读(ArkTS)…… HarmonyOS 概念https://qr21.cn/FV7h05
系统定义技术架构技术特性系统安全 如何快速入门https://qr21.cn/FV7h05
基本概念构建第一个ArkTS应用构建第一个JS应用…… 开发基础知识https://qr21.cn/FV7h05
应用基础知识配置文件应用数据管理应用安全管理应用隐私保护三方应用调用管控机制资源分类与访问学习ArkTS语言…… 基于ArkTS 开发https://qr21.cn/FV7h05
1.Ability开发 2.UI开发 3.公共事件与通知 4.窗口管理 5.媒体 6.安全 7.网络与链接 8.电话服务 9.数据管理 10.后台任务(Background Task)管理 11.设备管理 12.设备使用信息统计 13.DFX 14.国际化开发 15.折叠屏系列 16.……