您的当前位置:首页正文

HarmonyOS NEXT开发之ArkTS自定义组件学习笔记

2024-10-17 来源:个人技术集锦

在HarmonyOS中,ArkTS提供了创建自定义组件的能力,允许开发者封装和复用UI代码。以下是关于自定义组件的详细介绍,包括创建自定义组件、页面和自定义组件的生命周期、自定义组件的自定义布局、冻结功能,以及代码案例分析。

创建自定义组件

自定义组件是基于 struct 实现的,使用 @Component 装饰器来标识。每个自定义组件都必须实现 build() 方法,用于描述组件的UI结构。

@Componentstruct HelloComponent {  @State message: string = 'Hello, World!';  build() {    Row() {      Text(this.message)        .onClick(() => {          this.message = 'Hello, ArkUI!';        })    }  }}

在其他文件中使用该自定义组件时,需要使用 export 关键字导出,并在页面中使用 import 导入该组件 。

页面和自定义组件生命周期

页面生命周期仅限于被 @Entry 装饰的组件,而自定义组件的生命周期仅限于被 @Component 装饰的组件。

  • onPageShow :页面每次显示时触发。
  • onPageHide :页面每次隐藏时触发。
  • onBackPress :当用户点击返回按钮时触发。
  • aboutToAppear :组件即将出现时触发。
  • aboutToDisappear :组件即将销毁时触发 。

自定义组件的自定义布局

如果需要通过测算的方式布局自定义组件内子组件的位置,可以使用 onMeasureSize onPlaceChildren 接口。

@Componentstruct CustomLayout {  @Builder doNothingBuilder() {};  @BuilderParam builder: () => void = this.doNothingBuilder;  @State startSize: number = 100;  result: SizeResult = { width: 0, height: 0 };  onMeasureSize(selfLayoutInfo: GeometryInfo, children: Array<Measurable>, constraint: ConstraintSizeOptions) {    let size = 100;    children.forEach((child) => {      let result: MeasureResult = child.measure({ minHeight: size, minWidth: size, maxWidth: size, maxHeight: size });      size += result.width / 2;    });    this.result.width = 100;    this.result.height = 400;    return this.result;  }  onPlaceChildren(selfLayoutInfo: GeometryInfo, children: Array<Layoutable>, constraint: ConstraintSizeOptions) {    let startPos = 300;    children.forEach((child) => {      let pos = startPos - child.measureResult.height;      child.layout({ x: pos, y: pos });    });  }  build() {    this.builder();  }}

在这个例子中, CustomLayout 组件通过 onMeasureSize onPlaceChildren 设置了子组件的大小和位置 。

自定义组件冻结功能

从API version 12开始, @ComponentV2 装饰的自定义组件支持冻结功能。当组件处于非激活状态时,状态变量将不响应更新。

@Entry@ComponentV2({ freezeWhenInactive: true })struct FirstTest {  build() {    Column() {      Text(`From first Page ${book.page}`).fontSize(50)      Button('first page + 1').fontSize(30)        .onClick(() => {          book.page += 1;        })      Button('go to next page').fontSize(30)        .onClick(() => {          router.pushUrl({ url: 'pages/Page' });        })    }  }}

在这个例子中,当页面A跳转到页面B时,页面A的状态变为非激活,组件的更新将被冻结 。

通过这些功能,开发者可以创建可复用、响应式且具有复杂布局的自定义组件,从而提升HarmonyOS应用的开发效率和用户体验。

自定义组件案例:订单列表页面

假设我们需要开发一个HarmonyOS应用,其中包含一个订单列表页面。这个页面将显示一个订单项的自定义组件,每个订单项包含订单编号、日期和订单状态。我们希望这个自定义组件是可重用的,以便在应用的其他部分也可以使用它。

步骤 1: 创建自定义组件

首先,我们创建一个名为 OrderItem 的自定义组件,它将显示单个订单项的详细信息。

// OrderItem.ets@Componentexport struct OrderItem {  @Prop orderId: string;  @Prop orderDate: string;  @Prop status: string;  build() {    Row() {      Text(this.orderId).width(200).height(60).fontSize(16).alignItems(HorizontalAlign.Start);      Text(this.orderDate).width(150).height(60).fontSize(14).alignItems(HorizontalAlign.Center);      Text(this.status).width(100).height(60).fontSize(14).alignItems(HorizontalAlign.End);    }.padding(10).backgroundColor(Color.White).border({ width: 1, color: Color.Grey });  }}

在这个组件中,我们使用了 @Prop 装饰器来定义属性,这些属性将由父组件传递。 build() 方法定义了订单项的UI结构,使用了 Row 布局来水平排列订单编号、日期和状态。

步骤 2: 使用自定义组件

接下来,我们在订单列表页面中使用 OrderItem 组件来显示订单数据。

// OrderList.etsimport { OrderItem } from './OrderItem';@Entry@Componentstruct OrderList {  @State orders: Array<{ orderId: string; orderDate: string; status: string }> = [    { orderId: '001', orderDate: '2024-04-01', status: 'Completed' },    { orderId: '002', orderDate: '2024-04-02', status: 'Shipped' },    // 更多订单...  ];  build() {    Column() {      ForEach(this.orders, (order) => {        OrderItem({          orderId: order.orderId,          orderDate: order.orderDate,          status: order.status,        });      });    }.spacing(10).padding(10);  }}

OrderList 组件中,我们定义了一个状态变量 orders 来存储订单数据。在 build() 方法中,我们使用 ForEach 循环来遍历订单数组,并为每个订单创建一个 OrderItem 组件实例,传递相应的属性。

详细解释

  1. 自定义组件的定义 OrderItem 组件通过 @Component 装饰器定义,使其成为一个自定义组件。它接受三个属性: orderId orderDate status

  2. UI布局 :在 OrderItem build() 方法中,我们使用 Row 布局来水平排列三个 Text 组件,分别显示订单编号、日期和状态。每个 Text 组件都设置了宽度、高度、字体大小和对齐方式,以确保布局的整洁和一致性。

  3. 属性传递 OrderItem 组件的属性是通过 @Prop 装饰器定义的,这允许父组件 OrderList 在创建 OrderItem 实例时传递这些属性的值。

  4. 数据驱动 OrderList 组件的状态变量 orders 包含了订单数据。使用 ForEach 循环,我们为每个订单项创建一个 OrderItem 组件实例,并将订单数据作为属性传递给它。

  5. 重用性 OrderItem 组件是可重用的,因为它封装了订单项的UI和逻辑,可以在 OrderList 页面之外的其他部分使用,只需传递相应的属性即可。

好了,这个案例展示了如何创建和使用自定义组件来构建HarmonyOS应用的UI,以及如何通过属性传递和状态管理来实现数据驱动的UI更新。关注威哥爱编程,你会发现他的世界里,咖啡是燃料,键盘是乐器,而代码就是他的交响乐。每当夜深人静,别人数羊,威哥数的是代码行数。??‍??

显示全文