文档管理中心
您当前正在浏览HarmonyOS最新文档,覆盖已发布的所有API版本,可在API参考中筛选您使用的API版本。详细的版本配套关系请参考版本说明
API参考应用框架ArkUI(方舟UI框架)ArkTS组件通用属性动态属性与自定义自定义绘制设置

自定义绘制设置

当某些组件本身的绘制内容不满足需求时,可使用自定义组件绘制功能,在原有组件基础上部分绘制,或者全部自行绘制,以达到预期效果。例如:独特的按钮形状、文字和图像混合的图标等。自定义组件绘制提供了自定义绘制修改器,来实现更自由地组件绘制。

说明
  • 从API version 12开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。

  • 本模块接口仅可在Stage模型下使用。

drawModifier

PhonePC/2in1TabletTVWearable

drawModifier(modifier: DrawModifier | undefined): T

设置组件的自定义绘制修改器。

说明

该接口不支持在attributeModifier中调用。

元服务API: 从API version 12开始,该接口支持在元服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

组件支持范围:

AlphabetIndexerBadgeBlankButtonCalendarPickerCheckboxCheckboxGroupCircleColumnColumnSplitCounterDataPanelDatePickerEllipseFlexFlowItemFolderStackFormLinkGaugeGridGridColGridItemGridRowHyperlinkImageImageAnimatorImageSpanLineListListItemListItemGroupLoadingProgressMarqueeMenuMenuItemMenuItemGroupNavDestinationNavigationNavigatorNavRouterNodeContainerPathPatternLockPolygonPolylineProgressQRCodeRadioRatingRectRefreshRelativeContainerRichEditorRowRowSplitScrollScrollBarSearchSelectShapeSideBarContainerSliderStackStepperStepperItemSwiperSymbolGlyphTabContentTabsTextTextAreaTextClockTextInputTextPickerTextTimerTimePickerToggleWaterFlowXComponent

参数:

展开
参数名 类型 必填 说明
modifier DrawModifier | undefined

自定义绘制修改器,其中定义了自定义绘制的逻辑。

默认值:undefined

说明:

每个自定义修改器只对当前绑定组件的FrameNode生效,对其子节点不生效。

返回值:

展开
类型 说明
T 返回当前组件。

DrawModifier

PhonePC/2in1TabletTVWearable

DrawModifier可设置遮罩层前景(drawOverlay)、前景(drawForeground)、内容前景(drawFront)、内容(drawContent)和内容背景(drawBehind)的绘制方法,还提供主动触发重绘的方法invalidate。每个DrawModifier实例只能设置到一个组件上,禁止进行重复设置。

自定义层级示例图

元服务API: 从API version 12开始,该接口支持在元服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

drawFront

PhonePC/2in1TabletTVWearable

drawFront?(drawContext: DrawContext): void

自定义绘制内容前景的接口,若重载该方法则可进行内容前景的自定义绘制。

元服务API: 从API version 12开始,该接口支持在元服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

展开
参数名 类型 必填 说明
drawContext DrawContext 图形绘制上下文。

示例:

请参考示例1(通过DrawModifier进行自定义绘制)

drawContent

PhonePC/2in1TabletTVWearable

drawContent?(drawContext: DrawContext): void

自定义绘制内容的接口,若重载该方法则可进行内容的自定义绘制,会替换组件原本的内容绘制函数。

该接口的DrawContext中的Canvas是用于记录指令的临时Canvas,并非节点的真实Canvas。使用请参见调整自定义绘制Canvas的变换矩阵

元服务API: 从API version 12开始,该接口支持在元服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

展开
参数名 类型 必填 说明
drawContext DrawContext 图形绘制上下文。

示例:

请参考示例1(通过DrawModifier进行自定义绘制)

drawBehind

PhonePC/2in1TabletTVWearable

drawBehind?(drawContext: DrawContext): void

自定义绘制背景的接口,若重载该方法则可进行背景的自定义绘制。

元服务API: 从API version 12开始,该接口支持在元服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

展开
参数名 类型 必填 说明
drawContext DrawContext 图形绘制上下文。

示例:

请参考示例1(通过DrawModifier进行自定义绘制)

drawForeground20+

PhonePC/2in1TabletTVWearable

drawForeground(drawContext: DrawContext): void

自定义绘制前景的接口,若重载该方法则可进行前景的自定义绘制。需要对其组件的前景层进行绘制时重载该方法。

元服务API: 从API version 20开始,该接口支持在元服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

展开
参数名 类型 必填 说明
drawContext DrawContext 图形绘制上下文。

示例:

请参考示例2(通过DrawModifier对容器的前景进行自定义绘制)

drawOverlay23+

PhonePC/2in1TabletTVWearable

drawOverlay(drawContext: DrawContext): void

自定义绘制遮罩层的接口,若重载该方法则可进行遮罩层的自定义绘制。需要对其组件的遮罩层进行绘制时重载该方法。

元服务API: 从API version 23开始,该接口支持在元服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

展开
参数名 类型 必填 说明
drawContext DrawContext 图形绘制上下文。

示例:

收起
自动换行
深色代码主题
复制
  1. // test.ets
  2. import { drawing } from '@kit.ArkGraphics2D';
  3. class MyForegroundDrawModifier extends DrawModifier {
  4. public scaleX: number = 3;
  5. public scaleY: number = 3;
  6. uiContext: UIContext;
  7. constructor(uiContext: UIContext) {
  8. super();
  9. this.uiContext = uiContext;
  10. }
  11. // 重载drawOverlay方法,实现自定义绘制遮罩层前景
  12. drawOverlay(context: DrawContext): void {
  13. const brush = new drawing.Brush();
  14. brush.setColor({
  15. alpha: 255,
  16. red: 0,
  17. green: 50,
  18. blue: 100
  19. });
  20. context.canvas.attachBrush(brush);
  21. const halfWidth = context.size.width / 2;
  22. const halfHeight = context.size.height / 2;
  23. context.canvas.drawRect({
  24. left: this.uiContext.vp2px(halfWidth - 30 * this.scaleX),
  25. top: this.uiContext.vp2px(halfHeight - 30 * this.scaleY),
  26. right: this.uiContext.vp2px(halfWidth + 30 * this.scaleX),
  27. bottom: this.uiContext.vp2px(halfHeight + 60 * this.scaleY)
  28. });
  29. }
  30. }
  31. @Entry
  32. @Component
  33. struct DrawModifierExample {
  34. // 将自定义绘制遮罩层前景的类实例化,传入UIContext实例
  35. private overlayModifier: MyForegroundDrawModifier = new MyForegroundDrawModifier(this.getUIContext());
  36. build() {
  37. Column() {
  38. Text('此文本是子节点')
  39. .fontSize(36)
  40. .width('100%')
  41. .height('100%')
  42. .textAlign(TextAlign.Center)
  43. }
  44. .margin(50)
  45. .width(280)
  46. .height(300)
  47. .backgroundColor(0x87CEEB)
  48. // 调用此接口并传入自定义绘制前景的类实例,即可实现自定义绘制前景
  49. .drawModifier(this.overlayModifier)
  50. }
  51. }

invalidate

PhonePC/2in1TabletTVWearable

invalidate(): void

主动触发重绘的接口,开发者无需也无法重载,调用会触发所绑定组件的重绘。

元服务API: 从API version 12开始,该接口支持在元服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

示例:

请参考示例1(通过DrawModifier进行自定义绘制)

DrawContext

PhonePC/2in1TabletTVWearable

type DrawContext = import('../api/arkui/Graphics').DrawContext

元服务API: 从API version 12开始,该接口支持在元服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

展开
类型 说明
import('../api/arkui/Graphics').DrawContext 图形绘制上下文。

示例

PhonePC/2in1TabletTVWearable

示例1(通过DrawModifier进行自定义绘制)

通过DrawModifier对Text组件进行自定义绘制。

收起
自动换行
深色代码主题
复制
  1. // xxx.ets
  2. import { drawing } from '@kit.ArkGraphics2D';
  3. import { AnimatorResult } from '@kit.ArkUI';
  4. // 继承DrawModifier实现自定义绘制控制器
  5. class MyFullDrawModifier extends DrawModifier {
  6. public scaleX: number = 1;
  7. public scaleY: number = 1;
  8. uiContext: UIContext;
  9. constructor(uiContext: UIContext) {
  10. super();
  11. this.uiContext = uiContext;
  12. }
  13. // 重载drawBehind方法,自定义绘制背景
  14. drawBehind(context: DrawContext): void {
  15. const brush = new drawing.Brush();
  16. brush.setColor({
  17. alpha: 255,
  18. red: 255,
  19. green: 0,
  20. blue: 0
  21. });
  22. context.canvas.attachBrush(brush);
  23. const halfWidth = context.size.width / 2;
  24. const halfHeight = context.size.height / 2;
  25. context.canvas.drawRect({
  26. left: this.uiContext.vp2px(halfWidth - 50 * this.scaleX),
  27. top: this.uiContext.vp2px(halfHeight - 50 * this.scaleY),
  28. right: this.uiContext.vp2px(halfWidth + 50 * this.scaleX),
  29. bottom: this.uiContext.vp2px(halfHeight + 50 * this.scaleY)
  30. });
  31. }
  32. // 重载drawContent方法,自定义绘制内容
  33. drawContent(context: DrawContext): void {
  34. const brush = new drawing.Brush();
  35. brush.setColor({
  36. alpha: 255,
  37. red: 0,
  38. green: 255,
  39. blue: 0
  40. });
  41. context.canvas.attachBrush(brush);
  42. const halfWidth = context.size.width / 2;
  43. const halfHeight = context.size.height / 2;
  44. context.canvas.drawRect({
  45. left: this.uiContext.vp2px(halfWidth - 30 * this.scaleX),
  46. top: this.uiContext.vp2px(halfHeight - 30 * this.scaleY),
  47. right: this.uiContext.vp2px(halfWidth + 30 * this.scaleX),
  48. bottom: this.uiContext.vp2px(halfHeight + 30 * this.scaleY)
  49. });
  50. }
  51. // 重载drawFront方法,自定义绘制内容前景
  52. drawFront(context: DrawContext): void {
  53. const brush = new drawing.Brush();
  54. brush.setColor({
  55. alpha: 255,
  56. red: 0,
  57. green: 0,
  58. blue: 255
  59. });
  60. context.canvas.attachBrush(brush);
  61. const halfWidth = context.size.width / 2;
  62. const halfHeight = context.size.height / 2;
  63. const radiusScale = (this.scaleX + this.scaleY) / 2;
  64. context.canvas.drawCircle(this.uiContext.vp2px(halfWidth), this.uiContext.vp2px(halfHeight),
  65. this.uiContext.vp2px(20 * radiusScale));
  66. }
  67. }
  68. // 继承DrawModifier实现自定义绘制控制器,仅支持自定义绘制内容前景
  69. class MyFrontDrawModifier extends DrawModifier {
  70. public scaleX: number = 1;
  71. public scaleY: number = 1;
  72. uiContext: UIContext;
  73. constructor(uiContext: UIContext) {
  74. super();
  75. this.uiContext = uiContext;
  76. }
  77. drawFront(context: DrawContext): void {
  78. const brush = new drawing.Brush();
  79. brush.setColor({
  80. alpha: 255,
  81. red: 0,
  82. green: 0,
  83. blue: 255
  84. });
  85. context.canvas.attachBrush(brush);
  86. const halfWidth = context.size.width / 2;
  87. const halfHeight = context.size.height / 2;
  88. const radiusScale = (this.scaleX + this.scaleY) / 2;
  89. context.canvas.drawCircle(this.uiContext.vp2px(halfWidth), this.uiContext.vp2px(halfHeight),
  90. this.uiContext.vp2px(20 * radiusScale));
  91. }
  92. }
  93. @Entry
  94. @Component
  95. struct DrawModifierExample {
  96. private fullModifier: MyFullDrawModifier = new MyFullDrawModifier(this.getUIContext());
  97. private frontModifier: MyFrontDrawModifier = new MyFrontDrawModifier(this.getUIContext());
  98. private drawAnimator: AnimatorResult | undefined = undefined;
  99. @State modifier: DrawModifier = new MyFrontDrawModifier(this.getUIContext());
  100. private count = 0;
  101. // 创建Animator对象并设置动画
  102. create() {
  103. let self = this;
  104. this.drawAnimator = this.getUIContext().createAnimator({
  105. duration: 1000,
  106. easing: 'ease',
  107. delay: 0,
  108. fill: 'forwards',
  109. direction: 'normal',
  110. iterations: 1,
  111. begin: 0,
  112. end: 2
  113. });
  114. this.drawAnimator.onFrame = (value: number) => {
  115. console.info('frame value =', value);
  116. const tempModifier = self.modifier as MyFullDrawModifier | MyFrontDrawModifier;
  117. tempModifier.scaleX = Math.abs(value - 1);
  118. tempModifier.scaleY = Math.abs(value - 1);
  119. // 主动触发重绘
  120. self.modifier.invalidate();
  121. };
  122. }
  123. build() {
  124. Column() {
  125. Row() {
  126. Text('test text')
  127. .width(100)
  128. .height(100)
  129. .margin(10)
  130. .backgroundColor(Color.Gray)
  131. .onClick(() => {
  132. const tempModifier = this.modifier as MyFullDrawModifier | MyFrontDrawModifier;
  133. tempModifier.scaleX -= 0.1;
  134. tempModifier.scaleY -= 0.1;
  135. })
  136. .drawModifier(this.modifier)
  137. }
  138. Row() {
  139. Button('create')
  140. .width(100)
  141. .height(100)
  142. .borderRadius(50)
  143. .margin(10)
  144. .onClick(() => {
  145. this.create();
  146. })
  147. Button('play')
  148. .width(100)
  149. .height(100)
  150. .borderRadius(50)
  151. .margin(10)
  152. .onClick(() => {
  153. if (this.drawAnimator) {
  154. this.drawAnimator.play();
  155. }
  156. })
  157. Button('changeModifier')
  158. .width(100)
  159. .height(100)
  160. .borderRadius(50)
  161. .margin(10)
  162. .onClick(() => {
  163. this.count += 1;
  164. if (this.count % 2 === 1) {
  165. console.info('change to full modifier');
  166. this.modifier = this.fullModifier;
  167. } else {
  168. console.info('change to front modifier');
  169. this.modifier = this.frontModifier;
  170. }
  171. })
  172. }
  173. }
  174. .width('100%')
  175. .height('100%')
  176. }
  177. }

示例2(通过DrawModifier对容器的前景进行自定义绘制)

通过DrawModifier对Column容器的前景进行自定义绘制。

收起
自动换行
深色代码主题
复制
  1. // xxx.ets
  2. import { drawing } from '@kit.ArkGraphics2D';
  3. class MyForegroundDrawModifier extends DrawModifier {
  4. public scaleX: number = 3;
  5. public scaleY: number = 3;
  6. uiContext: UIContext;
  7. constructor(uiContext: UIContext) {
  8. super();
  9. this.uiContext = uiContext;
  10. }
  11. // 重载drawForeground方法,实现自定义绘制前景
  12. drawForeground(context: DrawContext): void {
  13. const brush = new drawing.Brush();
  14. brush.setColor({
  15. alpha: 255,
  16. red: 0,
  17. green: 50,
  18. blue: 100
  19. });
  20. context.canvas.attachBrush(brush);
  21. const halfWidth = context.size.width / 2;
  22. const halfHeight = context.size.height / 2;
  23. context.canvas.drawRect({
  24. left: this.uiContext.vp2px(halfWidth - 30 * this.scaleX),
  25. top: this.uiContext.vp2px(halfHeight - 30 * this.scaleY),
  26. right: this.uiContext.vp2px(halfWidth + 30 * this.scaleX),
  27. bottom: this.uiContext.vp2px(halfHeight + 30 * this.scaleY)
  28. });
  29. }
  30. }
  31. @Entry
  32. @Component
  33. struct DrawModifierExample {
  34. // 将自定义绘制前景的类实例化,传入UIContext实例
  35. private foregroundModifier: MyForegroundDrawModifier = new MyForegroundDrawModifier(this.getUIContext());
  36. build() {
  37. Column() {
  38. Text('此文本是子节点')
  39. .fontSize(36)
  40. .width('100%')
  41. .height('100%')
  42. .textAlign(TextAlign.Center)
  43. }
  44. .margin(50)
  45. .width(280)
  46. .height(300)
  47. .backgroundColor(0x87CEEB)
  48. // 调用此接口并传入自定义绘制前景的类实例,即可实现自定义绘制前景
  49. .drawModifier(this.foregroundModifier)
  50. }
  51. }

在 API参考 中进行搜索
请输入您想要搜索的关键词