自定义组件的生命周期

自定义组件的生命周期回调函数用于通知用户该自定义组件的生命周期,这些回调函数是私有的,在运行时由开发框架在特定的时间进行调用,不能从应用程序中手动调用这些回调函数。不要在多个窗口复用同一个自定义组件节点,其生命周期可能会紊乱。

aboutToAppear

aboutToAppear函数在创建自定义组件的新实例后,在执行其build()函数之前执行。允许在aboutToAppear函数中改变状态变量,更改将在后续执行build()函数中生效。实现自定义布局的自定义组件的aboutToAppear生命周期在布局过程中触发。

onDidBuild

onDidBuild函数在执行自定义组件build()函数之后执行。不建议在onDidBuild函数中更改状态变量、使用animateTo等功能,这可能会导致不稳定的UI表现。

aboutToDisappear

aboutToDisappear函数在自定义组件析构销毁时执行。不允许在aboutToDisappear函数中改变状态变量,特别是@Link变量的修改可能会导致应用程序行为不稳定。

onPageShow

页面每次显示时触发一次,包括路由过程、应用进入前台等场景,仅@Entry装饰的自定义组件生效。

onPageHide

页面每次隐藏时触发一次,包括路由过程、应用进入后台等场景,仅@Entry装饰的自定义组件生效。

onBackPress

当用户点击返回按钮时触发,仅@Entry装饰的自定义组件生效。返回true表示页面自己处理返回逻辑,不进行页面路由;返回false表示使用默认的路由返回逻辑,不设置返回值按照false处理。

代码如下:

// xxx.ets
@Entry
@Component
struct IndexComponent {
  @State textColor: Color = Color.Black;

  onPageShow() {
    this.textColor = Color.Blue;
    console.info('IndexComponent onPageShow');
  }

  onPageHide() {
    this.textColor = Color.Transparent;
    console.info('IndexComponent onPageHide');
  }

  onBackPress() {
    this.textColor = Color.Red;
    console.info('IndexComponent onBackPress');
  }

  build() {
    Column() {
      Text('Hello World')
        .fontColor(this.textColor)
        .fontSize(30)
        .margin(30)
    }.width('100%')
  }
}

自定义组件的自定义布局

自定义组件的自定义布局用于通过计算的方式布局自定义组件内的子组件。

onPlaceChilren

ArkUI框架会在自定义组件布局时,将该自定义组件的子节点自身的尺寸范围通过onPlaceChildren传递给该自定义组件。不允许在onPlaceChildren函数中改变状态变量。

onMeasureSize

ArkUI框架会在自定义组件确定尺寸时,将该自定义组件的节点信息和尺寸返回通过onMeasureSize传递给开发者。不允许在onMeasureSize函数中改变状态变量。

// xxx.ets
@Entry
@Component
struct Index {
  build() {
    Column() {
      CustomLayout({ builder: ColumnChildren })
    }
  }
}

@Builder
function ColumnChildren() {
  ForEach([1, 2, 3], (index: number) => { //暂不支持lazyForEach的写法
    Text('S' + index)
      .fontSize(30)
      .width(100)
      .height(100)
      .borderWidth(2)
      .offset({ x: 10, y: 20 })
  })
}

@Component
struct CustomLayout {
  @Builder
  doNothingBuilder() {
  };

  @BuilderParam builder: () => void = this.doNothingBuilder;
  @State startSize: number = 100;
  result: SizeResult = {
    width: 0,
    height: 0
  };

  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 })
    })
  }

  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;
  }

  build() {
    this.builder()
  }
}

自定义组件内置方法

自定义组件内置方法是由ArkUI开发框架提供给应用开发者,定义在自定义组件基类上的API。应用开发者可以在自定义组件的实例上调用对应的API以获取当前自定义组件实例相关的信息。例如,查询当前自定组件上下文的UIContext信息。

getUIContext

获取UIContext对象。

import { UIContext } from '@kit.ArkUI';

@Entry
@Component
struct MyComponent {
  aboutToAppear() {
    let uiContext: UIContext = this.getUIContext();
  }

  build() {
    // ...
  }
}

getUniqueId

获取当前Component的UniqueId。UniqueId为系统为每个组件分配的Id,可保证当前应用中的唯一性。若在组件对应的节点未创建或已销毁时获取,返回无效为-1

@Entry
@Component
struct MyComponent {
  aboutToAppear() {
    let uniqueId: number = this.getUniqueId();
  }

  build() {
    // ...
  }
}

queryNavDestinationInfo

查询自定义组件所属的NavDestination信息。

import { uiObserver } from '@kit.ArkUI'

@Component
export struct NavDestinationExample {
  build() {
    NavDestination() {
      MyComponent()
    }
  }
}

@Component
struct MyComponent {
  navDesInfo: uiObserver.NavDestinationInfo | undefined

  aboutToAppear() {
    // this指代MyComponent自定义节点,并从该节点向上查找其最近的一个类型为NavDestination的父亲节点
    this.navDesInfo = this.queryNavDestinationInfo();
    console.log('get navDestinationInfo: ' + JSON.stringify(this.navDesInfo))
  }

  build() {
    // ...
  }
}

queryNavigationInfo

查询自定义组件所属的Navigation信息。

// index.ets
import { uiObserver } from '@kit.ArkUI'

@Entry
@Component
struct MainPage {
  pathStack: NavPathStack = new NavPathStack()

  build() {
    Navigation(this.pathStack) {
      // ...
    }.id("NavigationId")
  }
}



@Component
export struct PageOne {
  pathStack: NavPathStack = new NavPathStack()

  aboutToAppear() {
    // this指代PageOne自定义节点,并从该节点向上查找其最近的一个类型为Navigation的父亲节点
    let navigationInfo: uiObserver.NavigationInfo | undefined = this.queryNavigationInfo()
    console.log('get navigationInfo: ' + JSON.stringify(navigationInfo))
    if (navigationInfo !== undefined) {
      this.pathStack = navigationInfo.pathStack
    }
  }

  build() {
    NavDestination() {
      // ...
    }.title('PageOne')
  }
}

queryRouterPageInfo

获取RouterPageInfo实例对象。

import { uiObserver } from '@kit.ArkUI'

@Entry
@Component
struct MyComponent {
  aboutToAppear() {
    let info: uiObserver.RouterPageInfo | undefined = this.queryRouterPageInfo();
  }

  build() {
    // ...
  }
}