自定义组件
自定义组件的生命周期
aboutToAppear
aboutToAppear 函数在创建自定义组件的新实例后,在执行其 build()函数之前执行。允许在 aboutToAppear 函数中改变状态变量,更改将在后续执行 build()函数中生效。实现自定义布局的自定义组件的 aboutToAppear 生命周期在布局过程中触发。
onDidBuild
onDidBuild 函数在执行自定义组件的 build()函数之后执行,开发者可以在这个阶段进行埋点数据上报等不影响实际 UI 的功能。不建议在 onDidBuild 函数中更改状态变量、使用 animateTo 等功能,这可能会导致不稳定的 UI 表现。
onPageShow
页面每次显示时触发一次,包括路由过程、应用进入前台等场景,仅@Entry 装饰的自定义组件作为页面时生效。
onPageHide
页面每次隐藏时触发一次,包括路由过程、应用进入后台等场景,仅@Entry 装饰的自定义组件作为页面时生效。
onBackPress
当用户点击返回按钮时触发,仅@Entry
装饰的自定义组件作为页面时生效。返回 true 表示页面自己处理返回逻辑,不进行页面路由;返回 false 表示使用默认的路由返回逻辑,不设置返回值按照 false 处理。
aboutToDisappear
函数在自定义组件析构销毁时执行。不允许在 aboutToDisappear 函数中改变状态变量,特别是@Link 变量的修改可能会导致应用程序行为不稳定。
示例
// 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%')
}
}
aboutToReuse
当一个可复用的自定义组件从复用缓存中重新加入到节点树时,触发 aboutToReuse 生命周期回调,并将组件的构造参数传递给 aboutToReuse。
// xxx.ets
export class Message {
value: string | undefined;
constructor(value: string) {
this.value = value
}
}
@Entry
@Component
struct Index {
@State switch: boolean = true
build() {
Column() {
Button('Hello World')
.fontSize(50)
.fontWeight(FontWeight.Bold)
.onClick(() => {
this.switch = !this.switch
})
if (this.switch) {
Child({ message: new Message('Child') })
}
}
.height("100%")
.width('100%')
}
}
@Reusable
@Component
struct Child {
@State message: Message = new Message('AboutToReuse');
aboutToReuse(params: Record<string, ESObject>) {
console.info("Recycle Child")
this.message = params.message as Message
}
build() {
Column() {
Text(this.message.value)
.fontSize(20)
}
.borderWidth(2)
.height(100)
}
}
aboutToRecycle
组件的生命周期回调,在可复用组件从组件树上被加入到复用缓存之前调用。
// xxx.ets
export class Message {
value: string | undefined;
constructor(value: string) {
this.value = value;
}
}
@Entry
@Component
struct Index {
@State switch: boolean = true;
build() {
Column() {
Button('Hello World')
.fontSize(50)
.fontWeight(FontWeight.Bold)
.onClick(() => {
this.switch = !this.switch;
})
if (this.switch) {
Child({ message: new Message('Child') })
}
}
.height("100%")
.width('100%')
}
}
@Reusable
@Component
struct Child {
@State message: Message = new Message('AboutToReuse');
aboutToReuse(params: Record<string, ESObject>) {
console.info("Reuse Child");
this.message = params.message as Message;
}
aboutToRecycle() {
//这里可以释放比较占内存的内容或其他非必要资源引用,避免一直占用内存,引发内存泄漏
console.info("Recycle Child,child进入复用池中");
}
build() {
Column() {
Text(this.message.value)
.fontSize(20)
}
.borderWidth(2)
.height(100)
}
}
onWillApplyTheme
onWillApplyTheme 函数用于获取当前组件上下文的 Theme 对象,在创建自定义组件的新实例后,在执行其 build()
函数之前执行。允许在 onWillApplyTheme 函数中改变状态变量,更改将在后续执行 build()
函数中生效。
// xxx.ets
import { CustomTheme, CustomColors, Theme, ThemeControl } from '@kit.ArkUI';
class BlueColors implements CustomColors {
fontPrimary = Color.White;
backgroundPrimary = Color.Blue;
brand = Color.Blue; //品牌色
}
class PageCustomTheme implements CustomTheme {
colors?: CustomColors;
constructor(colors: CustomColors) {
this.colors = colors;
}
}
const BlueColorsTheme = new PageCustomTheme(new BlueColors());
// setDefaultTheme应该在应用入口页面调用或者在Ability中调用。
ThemeControl.setDefaultTheme(BlueColorsTheme);
@Entry
@Component
struct IndexComponent {
@State textColor: ResourceColor = $r('sys.color.font_primary');
@State columBgColor: ResourceColor = $r('sys.color.background_primary');
// onWillApplyTheme中可获取当前组件上下文的Theme对象。此处在onWillApplyTheme中将状态变量textColor、columBgColor,赋值为当前使用的Theme对象(BlueColorsTheme)中的配色。
onWillApplyTheme(theme: Theme) {
this.textColor = theme.colors.fontPrimary;
this.columBgColor = theme.colors.backgroundPrimary;
console.info('IndexComponent onWillApplyTheme');
}
build() {
Column() {
// 组件初始值配色样式
Column() {
Text('Hello World')
.fontColor($r('sys.color.font_primary'))
.fontSize(30)
}
.width('100%')
.height('25%')
.borderRadius('10vp')
.backgroundColor($r('sys.color.background_primary'))
// 组件颜色生效为onWillApplyTheme中配置颜色。
Column() {
Text('onWillApplyTheme')
.fontColor(this.textColor)
.fontSize(30)
Text('Hello World')
.fontColor(this.textColor)
.fontSize(30)
}
.width('100%')
.height('25%')
.borderRadius('10vp')
.backgroundColor(this.columBgColor)
}
.padding('16vp')
.backgroundColor('#dcdcdc')
.width('100%')
.height('100%')
}
}
自定义组件内置方法
自定义组件内置方法是由 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,可保证当前应用中的唯一性。若在组件对应的节点未创建或已销毁时获取,返回无效 UniqueId:-1。
@Entry
@Component
struct MyComponent {
aboutToAppear() {
let uniqueId: number = this.getUniqueId();
}
build() {
// ...
}
}
queryNavDestinationInfo
查询自定义组件所属的 NavDestination 信息,仅当自定义组件在 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() {
// ...
}
}