1# RichEditor 2 3支持图文混排和文本交互式编辑的组件。 4 5> **说明:** 6> 7> 该组件从API Version 10开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 8 9 10## 子组件 11 12不包含子组件。 13 14 15## 接口 16 17RichEditor(value: RichEditorOptions) 18 19**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 20 21**系统能力:** SystemCapability.ArkUI.ArkUI.Full 22 23**参数:** 24 25| 参数名 | 类型 | 必填 | 说明 | 26| ----- | --------------------------------------- | ---- | ----------- | 27| value | [RichEditorOptions](#richeditoroptions) | 是 | 富文本组件初始化选项。 | 28 29RichEditor(options: RichEditorStyledStringOptions)<sup>12+</sup> 30 31 32**参数:** 33 34| 参数名 | 类型 | 必填 | 说明 | 35| ----- | --------------------------------------- | ---- | ----------- | 36| options | [RichEditorStyledStringOptions](#richeditorstyledstringoptions12) | 是 | 富文本组件初始化选项。 | 37 38## 属性 39 40除支持[通用属性](ts-component-general-attributes.md)外,还支持以下属性: 41 42> **说明:** 43> 44> align属性只支持上方、中间和下方位置的对齐方式。 45> 46> 不支持borderImage属性。 47 48### customKeyboard 49 50customKeyboard(value: CustomBuilder, options?: KeyboardOptions) 51 52设置自定义键盘。 53 54当设置自定义键盘时,输入框激活后不会打开系统输入法,而是加载指定的自定义组件。 55 56自定义键盘的高度可以通过自定义组件根节点的height属性设置,宽度不可设置,使用系统默认值。 57 58自定义键盘无法获取焦点,但是会拦截手势事件。 59 60默认在输入控件失去焦点时,关闭自定义键盘。 61 62如果设备支持拍摄输入,设置自定义键盘后,该输入框会不支持拍摄输入。 63 64**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 65 66**系统能力:** SystemCapability.ArkUI.ArkUI.Full 67 68**参数:** 69 70| 参数名 | 类型 | 必填 | 说明 | 71| --------------------- | ------------------------------------------- | ---- | -------------------------------- | 72| value | [CustomBuilder](ts-types.md#custombuilder8) | 是 | 自定义键盘。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。| 73| options<sup>12+</sup> | [KeyboardOptions](#keyboardoptions12) | 否 | 设置自定义键盘是否支持避让功能。 | 74 75### bindSelectionMenu 76 77bindSelectionMenu(spanType: RichEditorSpanType, content: CustomBuilder, responseType: ResponseType | RichEditorResponseType, 78 options?: SelectionMenuOptions) 79 80设置自定义选择菜单。自定义菜单超长时,建议内部嵌套[Scroll](./ts-container-scroll.md)组件使用,避免键盘被遮挡。 81 82**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 83 84**系统能力:** SystemCapability.ArkUI.ArkUI.Full 85 86**参数:** 87 88| 参数名 | 类型 | 必填 | 说明 | 89| ------------ | ------------------------------------------------------------ | ---- | --------------------------------------------------------- | 90| spanType | [RichEditorSpanType](#richeditorspantype) | 是 | 菜单的类型。<br/> 默认值:<br/>RichEditorSpanType.TEXT | 91| content | [CustomBuilder](ts-types.md#custombuilder8) | 是 | 菜单的内容。 | 92| responseType | [ResponseType](ts-appendix-enums.md#responsetype8) \| [RichEditorResponseType](#richeditorresponsetype11) | 是 | 菜单的响应类型。<br/> 默认值:<br/>ResponseType.LongPress | 93| options | [SelectionMenuOptions](#selectionmenuoptions10) | 否 | 菜单的选项。 | 94 95### copyOptions 96 97copyOptions(value: CopyOptions) 98 99设置组件是否支持文本内容可复制粘贴。 100 101copyOptions不为CopyOptions.None时,长按组件内容,会弹出文本选择弹框。如果通过bindSelectionMenu等方式自定义文本选择菜单,则会弹出自定义的菜单。 102 103设置copyOptions为CopyOptions.None,复制、剪切、翻译、帮写功能不生效。 104 105**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 106 107**系统能力:** SystemCapability.ArkUI.ArkUI.Full 108 109**参数:** 110 111| 参数名 | 类型 | 必填 | 说明 | 112| ------ | ------------------------------------------------ | ---- | ------------------------------------------------------------ | 113| value | [CopyOptions](ts-appendix-enums.md#copyoptions9) | 是 | 组件支持文本内容是否可复制粘贴。<br />默认值:CopyOptions.LocalDevice | 114 115### enableDataDetector<sup>11+</sup> 116 117enableDataDetector(enable: boolean) 118 119设置是否进行文本特殊实体识别。 120 121该接口依赖设备底层应具有文本识别能力,否则设置不会生效。 122 123当enableDataDetector设置为true,同时不设置dataDetectorConfig属性时,默认识别所有类型的实体,所识别实体的color和decoration会被更改为如下样式: 124 125```ts 126color: '#ff007dff' 127decoration:{ 128 type: TextDecorationType.Underline, 129 color: '#ff007dff', 130 style: TextDecorationStyle.SOLID 131} 132``` 133 134触摸点击和鼠标右键点击实体,会根据实体类型弹出对应的实体操作菜单,鼠标左键点击实体会直接响应菜单的第一个选项。 135 136对addBuilderSpan的节点文本,该功能不会生效。 137 138当copyOption设置为CopyOptions.None时,点击实体弹出的菜单没有选择文本和复制功能。 139 140**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 141 142**系统能力:** SystemCapability.ArkUI.ArkUI.Full 143 144**参数:** 145 146| 参数名 | 类型 | 必填 | 说明 | 147| ------ | ------- | ---- | --------------------------------- | 148| enable | boolean | 是 | 使能文本识别。<br/>默认值: false | 149 150### dataDetectorConfig<sup>11+</sup> 151 152dataDetectorConfig(config: TextDataDetectorConfig) 153 154设置文本识别配置。 155 156需配合[enableDataDetector](#enabledatadetector11)一起使用,设置enableDataDetector为true时,dataDetectorConfig的配置才能生效。 157 158当有两个实体A、B重叠时,按以下规则保留实体: 159 1601. 若A ⊂ B,则保留B,反之则保留A。 161 1622. 当A ⊄ B且B ⊄ A时,若A.start < B.start,则保留A,反之则保留B。 163 164**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 165 166**系统能力:** SystemCapability.ArkUI.ArkUI.Full 167 168**参数:** 169 170| 参数名 | 类型 | 必填 | 说明 | 171| ------ | ----------------------------------------------------------- | ---- | ------------------------------------------------------------ | 172| config | [TextDataDetectorConfig](ts-text-common.md#textdatadetectorconfig11对象说明) | 是 | 文本识别配置。| 173 174### enablePreviewText<sup>12+</sup> 175 176enablePreviewText(enable: boolean) 177 178设置是否开启预上屏功能。 179 180**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 181 182**系统能力:** SystemCapability.ArkUI.ArkUI.Full 183 184**参数:** 185 186| 参数名 | 类型 | 必填 | 说明 | 187| ------ | ------- | ---- | --------------------------------- | 188| enable | boolean | 是 | 使能预上屏功能。<br/>默认值: true | 189 190> **说明:** 191> 192> 该接口在CAPI场景使用时下,默认关闭。可以在工程的module.json5中配置[metadata](../../../../application-dev/quick-start/module-structure.md#metadata对象内部结构)字段控制是否启用预上屏,配置如下: 193> ```json 194> "metadata": [ 195> { 196> "name": "can_preview_text", 197> "value": "true", 198> } 199> ] 200> ``` 201 202### placeholder<sup>12+</sup> 203 204placeholder(value: ResourceStr, style?: PlaceholderStyle) 205 206设置无输入时的提示文本。 207 208**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 209 210**系统能力:** SystemCapability.ArkUI.ArkUI.Full 211 212**参数:** 213 214| 参数名 | 类型 | 必填 | 说明 | 215| ------ | --------------------------------------- | ---- | ------------------------------------------------------- | 216| value | [ResourceStr](ts-types.md#resourcestr) | 是 | 无输入时的提示文本。 | 217| style | [PlaceholderStyle](#placeholderstyle12) | 否 | 添加提示文本的字体样式。<br />style缺省时默认跟随主题。 | 218 219### caretColor<sup>12+</sup> 220 221caretColor(value: ResourceColor) 222 223设置输入框光标、手柄颜色。 224 225**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 226 227**系统能力:** SystemCapability.ArkUI.ArkUI.Full 228 229**参数:** 230 231| 参数名 | 类型 | 必填 | 说明 | 232| ------ | ------------------------------------------ | ---- | -------------------------------------- | 233| value | [ResourceColor](ts-types.md#resourcecolor) | 是 | 输入框光标、手柄颜色。<br/>默认值:'#007DFF' | 234 235### selectedBackgroundColor<sup>12+</sup> 236 237selectedBackgroundColor(value: ResourceColor) 238 239设置文本选中底板颜色。如果未设置不透明度,默认为20%不透明度。 240 241**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 242 243**系统能力:** SystemCapability.ArkUI.ArkUI.Full 244 245**参数:** 246 247| 参数名 | 类型 | 必填 | 说明 | 248| ------ | ------------------------------------------ | ---- | ------------------------------------------ | 249| value | [ResourceColor](ts-types.md#resourcecolor) | 是 | 文本选中底板颜色。<br/>默认为20%不透明度。 | 250 251### editMenuOptions<sup>12+</sup> 252 253editMenuOptions(editMenu: EditMenuOptions) 254 255设置自定义菜单扩展项,允许用户设置扩展项的文本内容、图标、回调方法。 256 257**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 258 259**元服务API:** 从API version 12开始,该接口支持在元服务中使用。 260 261**系统能力:** SystemCapability.ArkUI.ArkUI.Full 262 263**参数:** 264 265| 参数名 | 类型 | 必填 | 说明 | 266| ------ | --------------------------------------------- | ---- | --------------------------------------------- | 267| editMenu | [EditMenuOptions](ts-text-common.md#editmenuoptions) | 是 | 扩展菜单选项。 | 268 269### enterKeyType<sup>12+</sup> 270 271enterKeyType(value: EnterKeyType) 272 273设置软键盘输入法回车键类型。 274 275**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 276 277**系统能力:** SystemCapability.ArkUI.ArkUI.Full 278 279**参数:** 280 281| 参数名 | 类型 | 必填 | 说明 | 282| ------ | ------ | ---- | ----------------------------------- | 283| value | [EnterKeyType](ts-basic-components-textinput.md#enterkeytype枚举说明) | 是 | 键盘输入法回车键类型。<br/>默认为EnterKeyType.NEW_LINE。 | 284 285### enableKeyboardOnFocus<sup>12+</sup> 286 287enableKeyboardOnFocus(isEnabled: boolean) 288 289设置RichEditor通过点击以外的方式获焦时,是否主动拉起软键盘。 290 291 292**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 293 294**系统能力:** SystemCapability.ArkUI.ArkUI.Full 295 296**参数:** 297 298| 参数名 | 类型 | 必填 | 说明 | 299| ------ | ------- | ---- | ----------------------------------------------------------- | 300| isEnabled | boolean | 是 | 通过点击以外的方式获焦时,是否主动拉起软键盘。<br/>默认值:true | 301 302### barState<sup>13+</sup> 303 304barState(state: BarState) 305 306设置RichEditor编辑态时滚动条的显示模式。 307 308**原子化服务API:** 从API version 13开始,该接口支持在原子化服务中使用。 309 310**系统能力:** SystemCapability.ArkUI.ArkUI.Full 311 312**参数:** 313 314| 参数名 | 类型 | 必填 | 说明 | 315| ------ | ----------------------------------------- | ---- | ------------------------------------------------------ | 316| state | [BarState](ts-appendix-enums.md#barstate) | 是 | 输入框编辑态时滚动条的显示模式。<br/>默认值:BarState.Auto | 317 318### enableHapticFeedback<sup>13+</sup> 319 320enableHapticFeedback(isEnabled: boolean) 321 322设置RichEditor是否支持触控反馈。 323 324**原子化服务API:** 从API version 13开始,该接口支持在原子化服务中使用。 325 326**系统能力:** SystemCapability.ArkUI.ArkUI.Full 327 328| 参数名 | 类型 | 必填 | 说明 | 329| ------ | --------------------------------------------- |-----|-------------------------------------------------------------------------------------| 330| isEnabled | boolean | 是 | 是否支持触控反馈。<br/>默认值:true,true表示开启触控反馈,false表示不开启触控反馈。<br/>设置为true后是否生效,还取决于系统的硬件是否支持。 | 331 332### keyboardAppearance<sup>15+</sup> 333 334keyboardAppearance(appearance: Optional\<KeyboardAppearance\>) 335 336设置键盘外观。 337 338**原子化服务API:** 从API version 15开始,该接口支持在原子化服务中使用。 339 340**系统能力:** SystemCapability.ArkUI.ArkUI.Full 341 342**参数:** 343 344| 参数名 | 类型 | 必填 | 说明 | 345| ------ | ----------------------------------------- | ---- | ------------------------------------------------------ | 346| appearance | [Optional](ts-universal-attributes-custom-property.md#optional12)\<[KeyboardAppearance](ts-text-common.md#keyboardappearance15枚举说明)\> | 是 | 键盘的外观。<br/>默认值:KeyboardAppearance.NONE_IMMERSIVE | 347 348## 事件 349 350除支持[通用事件](ts-component-general-events.md)外,还支持[OnDidChangeCallback](ts-text-common.md#ondidchangecallback12)、[StyledStringChangedListener](ts-text-common.md#styledstringchangedlistener12)、[StyledStringChangeValue](ts-text-common.md#styledstringchangevalue12)和以下事件: 351 352### onReady 353 354onReady(callback:Callback\<void\>) 355 356富文本组件初始化完成后,触发回调。 357 358**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 359 360**系统能力:** SystemCapability.ArkUI.ArkUI.Full 361 362**参数:** 363 364| 参数名 | 类型 | 必填 | 说明 | 365| ----- | --------------------------------------- | ---- | ----------- | 366| callback |Callback\<void\> | 是 | 订阅富文本组件初始化完成的回调。 | 367 368### onSelect 369 370onSelect(callback:Callback\<[RichEditorSelection](#richeditorselection)\>) 371 372鼠标左键双击选中内容时,会触发回调;松开鼠标左键后,会再次触发回调。 373 374手指长按选中内容时,会触发回调;松开手指后,会再次触发回调。 375 376使用[RichEditorStyledStringOptions](#richeditorstyledstringoptions12)构建的RichEditor组件时不支持该回调。 377 378**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 379 380**系统能力:** SystemCapability.ArkUI.ArkUI.Full 381 382**参数:** 383 384| 参数名 | 类型 | 必填 | 说明 | 385| ------ | ------------------------------------------- | ---- | -------------------- | 386| callback | Callback\<[RichEditorSelection](#richeditorselection)\> | 是 | [RichEditorSelection](#richeditorselection)为选中的所有span信息。<br/>选择时触发的回调。 | 387 388### aboutToIMEInput 389 390aboutToIMEInput(callback:Callback\<[RichEditorInsertValue](#richeditorinsertvalue), boolean\>) 391 392输入法输入内容前,触发回调。 393 394使用[RichEditorStyledStringOptions](#richeditorstyledstringoptions12)构建的RichEditor组件时不支持该回调。 395 396**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 397 398**系统能力:** SystemCapability.ArkUI.ArkUI.Full 399 400**参数:** 401 402| 参数名 | 类型 | 必填 | 说明 | 403| ------ | ------------------------------------------- | ---- | -------------------- | 404| callback | Callback\<[RichEditorInsertValue](#richeditorinsertvalue), boolean\> | 是 | [RichEditorInsertValue](#richeditorinsertvalue)为输入法将要输入内容信息。<br/>true:组件执行添加内容操作。<br/>false:组件不执行添加内容操作。<br/>输入法输入内容前的回调。| 405 406### onDidIMEInput<sup>12+</sup> 407 408onDidIMEInput(callback:Callback\<TextRange>) 409 410输入法完成输入时,触发回调。 411 412使用[RichEditorStyledStringOptions](#richeditorstyledstringoptions12)构建的RichEditor组件时不支持该回调。 413 414**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 415 416**系统能力:** SystemCapability.ArkUI.ArkUI.Full 417 418**参数:** 419 420| 参数名 | 类型 | 必填 | 说明 | 421| ------ | ------------------------------------------- | ---- | -------------------- | 422| callback | Callback\<[TextRange](ts-text-common.md#textrange12)\> | 是 | TextRange为输入法本次输入内容的范围。<br/>输入法完成输入时的回调。| 423 424 425### onIMEInputComplete 426 427onIMEInputComplete(callback:Callback\<[RichEditorTextSpanResult](#richeditortextspanresult)\>) 428 429输入法完成输入后,触发回调。 430 431使用[RichEditorStyledStringOptions](#richeditorstyledstringoptions12)构建的RichEditor组件时不支持该回调。 432 433**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 434 435**系统能力:** SystemCapability.ArkUI.ArkUI.Full 436 437**参数:** 438 439| 参数名 | 类型 | 必填 | 说明 | 440| ------ | ------------------------------------------- | ---- | -------------------- | 441| callback | Callback\<[RichEditorTextSpanResult](#richeditortextspanresult)\> | 是 | [RichEditorTextSpanResult](#richeditortextspanresult)为输入法完成输入后的文本Span信息。<br/>输入法完成输入后的回调。| 442 443### aboutToDelete 444 445aboutToDelete(callback:Callback\<[RichEditorDeleteValue](#richeditordeletevalue), boolean\>) 446 447输入法删除内容前,触发回调。 448 449使用[RichEditorStyledStringOptions](#richeditorstyledstringoptions12)构建的RichEditor组件时不支持该回调。 450 451**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 452 453**系统能力:** SystemCapability.ArkUI.ArkUI.Full 454 455**参数:** 456 457| 参数名 | 类型 | 必填 | 说明 | 458| ------ | ------------------------------------------- | ---- | -------------------- | 459| callback | Callback\<[RichEditorDeleteValue](#richeditordeletevalue), boolean\> | 是 | [RichEditorDeleteValue](#richeditordeletevalue)为准备删除的内容所在的文本或者图片Span信息。<br/>true:组件执行删除操作。<br/>false:组件不执行删除操作。<br/>输入法删除内容前的回调,英文预上屏点击候选词时会执行该回调。| 460 461### onDeleteComplete 462 463onDeleteComplete(callback:Callback\<void\>) 464 465输入法完成删除后,触发回调。 466 467使用[RichEditorStyledStringOptions](#richeditorstyledstringoptions12)构建的RichEditor组件时不支持该回调。 468 469**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 470 471**系统能力:** SystemCapability.ArkUI.ArkUI.Full 472 473**参数:** 474 475| 参数名 | 类型 | 必填 | 说明 | 476| ----- | --------------------------------------- | ---- | ----------- | 477| callback |Callback\<void\> | 是 | 订阅输入法完成删除的回调。 | 478 479### onPaste<sup>11+</sup> 480 481onPaste(callback: [PasteEventCallback](#pasteeventcallback12) ) 482 483完成粘贴前,触发回调。开发者可以通过该方法,覆盖系统默认行为,实现图文的粘贴。 484 485**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 486 487**系统能力:** SystemCapability.ArkUI.ArkUI.Full 488 489**参数:** 490 491| 参数名 | 类型 | 必填 | 说明 | 492| ------ | ------- | ---- | ----------------------------- | 493| callback | [PasteEventCallback](#pasteeventcallback12) | 是 | 订阅完成粘贴前的回调。 | 494 495### onSelectionChange<sup>12+</sup> 496 497onSelectionChange(callback:Callback\<[RichEditorRange](#richeditorrange)\>) 498 499组件内所有内容选择区域发生变化或编辑状态下光标位置发生变化时触发该回调。光标位置发生变化回调时,选择区域的起始位置等于终止位置。 500 501**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 502 503**系统能力:** SystemCapability.ArkUI.ArkUI.Full 504 505**参数:** 506 507| 参数名 | 类型 | 必填 | 说明 | 508| ----- | --------------------------------------- | ---- | ----------- | 509| callback |Callback\<[RichEditorRange](#richeditorrange)\> | 是 | [RichEditorRange](#richeditorrange)为所有内容的选择区域起始和终止位置。<br/>订阅文本选择区域发生变化或编辑状态下光标位置发生变化时触发的回调。| 510 511### onEditingChange<sup>12+</sup> 512 513onEditingChange(callback: Callback\<boolean\>) 514 515组件内所有内容的编辑状态发生改变时触发该回调函数。 516 517**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 518 519**系统能力:** SystemCapability.ArkUI.ArkUI.Full 520 521**参数:** 522 523| 参数名 | 类型 | 必填 | 说明 | 524| ----- | --------------------------------------- | ---- | ----------- | 525| callback | Callback\<boolean\> | 是 | true表示编辑态,false表示非编辑态。 | 526 527### onSubmit<sup>12+</sup> 528 529onSubmit(callback: SubmitCallback) 530 531按下软键盘输入法回车键触发该回调。 532 533**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 534 535**系统能力:** SystemCapability.ArkUI.ArkUI.Full 536 537**参数:** 538 539| 参数名 | 类型 | 必填 | 说明 | 540| ------ | ------- | ---- | ----------------------------- | 541| callback | [SubmitCallback](#submitcallback12) | 是 | 侦听事件的回调。 | 542 543### onWillChange<sup>12+</sup> 544 545onWillChange(callback: Callback\<RichEditorChangeValue, boolean\>) 546 547组件执行增删操作前,触发回调。 548 549使用[RichEditorStyledStringOptions](#richeditorstyledstringoptions12)构建的RichEditor组件时不支持该回调。 550 551**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 552 553**系统能力:** SystemCapability.ArkUI.ArkUI.Full 554 555**参数:** 556 557| 参数名 | 类型 | 必填 | 说明 | 558| -- | -- | -- | -- | 559| callback | Callback\<[RichEditorChangeValue](#richeditorchangevalue12) , boolean\> | 是 | [RichEditorChangeValue](#richeditorchangevalue12)为图文变化信息;boolean表示当前图文是否允许被更改,true:允许图文被更改。false:不允许图文被更改。 | 560 561### onDidChange<sup>12+</sup> 562 563onDidChange(callback: OnDidChangeCallback) 564 565组件执行增删操作后,触发回调。文本实际未发生增删时,不触发该回调。 566 567使用[RichEditorStyledStringOptions](#richeditorstyledstringoptions12)构建的RichEditor组件时不支持该回调。 568 569**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 570 571**系统能力:** SystemCapability.ArkUI.ArkUI.Full 572 573**参数:** 574 575| 参数名 | 类型 | 必填 | 说明 | 576| -- | -- | -- | -- | 577| callback | [OnDidChangeCallback](ts-text-common.md#ondidchangecallback12) | 是 | 图文变化前后的内容范围。 | 578 579### onCut<sup>12+</sup> 580 581onCut(callback: Callback\<CutEvent\>) 582 583完成剪切前,触发回调。系统的默认剪切行为,只支持纯文本的剪切。开发者可以通过该方法,覆盖系统默认行为,实现图文的剪切。 584 585**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 586 587**系统能力:** SystemCapability.ArkUI.ArkUI.Full 588 589**参数:** 590 591| 参数名 | 类型 | 必填 | 说明 | 592| ----- | --------------------------------------- | ---- | ----------- | 593| callback |Callback\<[CutEvent](#cutevent12)\> | 是 | 定义用户剪切事件。 | 594 595### onCopy<sup>12+</sup> 596 597onCopy(callback: Callback\<CopyEvent\>) 598 599完成复制前,触发回调。系统的默认复制行为,只支持纯文本的复制。开发者可以通过该方法,覆盖系统默认行为,实现图文的复制。 600 601**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 602 603**系统能力:** SystemCapability.ArkUI.ArkUI.Full 604 605**参数:** 606 607| 参数名 | 类型 | 必填 | 说明 | 608| ----- | --------------------------------------- | ---- | ----------- | 609| callback |Callback\<[CopyEvent](#copyevent12)\> | 是 | 定义用户复制事件。 | 610 611## RichEditorInsertValue 612 613插入文本信息。 614 615**系统能力:** SystemCapability.ArkUI.ArkUI.Full 616 617| 名称 | 类型 | 必填 | 说明 | 618| ------------ | ------ | ---- | ---------- | 619| insertOffset | number | 是 | 插入的文本偏移位置。<br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。| 620| insertValue | string | 是 | 插入的文本内容。<br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 | 621| previewText<sup>12+</sup> | string | 否 | 插入的预上屏文本内容。<br/> **原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。| 622 623 624## RichEditorDeleteValue 625 626删除操作的信息和被删除内容的信息。 627 628**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 629 630**系统能力:** SystemCapability.ArkUI.ArkUI.Full 631 632| 名称 | 类型 | 必填 | 说明 | 633| --------------------- | ---------------------------------------- | ---- | ------------------- | 634| offset | number | 是 | 删除内容的偏移位置。 | 635| direction | [RichEditorDeleteDirection](#richeditordeletedirection) | 是 | 删除操作的方向。 | 636| length | number | 是 | 删除内容长度。 | 637| richEditorDeleteSpans | Array<[RichEditorTextSpanResult](#richeditortextspanresult) \| [RichEditorImageSpanResult](#richeditorimagespanresult)> | 是 | 删除的文本或者图片Span的具体信息。 | 638 639 640## RichEditorDeleteDirection 641 642删除操作的方向。 643 644**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 645 646**系统能力:** SystemCapability.ArkUI.ArkUI.Full 647 648| 名称 | 说明 | 649| -------- | ---------- | 650| BACKWARD | 向后删除。 | 651| FORWARD | 向前删除。 | 652 653 654## RichEditorTextSpanResult 655 656文本Span信息。 657 658**系统能力:** SystemCapability.ArkUI.ArkUI.Full 659 660| 名称 | 类型 | 必填 | 说明 | 661| ----------------------------- | ---------------------------------------- | ---- | ---------------------- | 662| spanPosition | [RichEditorSpanPosition](#richeditorspanposition) | 是 | Span位置。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。| 663| value | string | 是 | 文本Span内容或Symbol的id。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。| 664| textStyle | [RichEditorTextStyleResult](#richeditortextstyleresult) | 是 | 文本Span样式信息。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。| 665| offsetInSpan | [number, number] | 是 | 文本Span内容里有效内容的起始和结束位置。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。| 666| valueResource<sup>11+</sup> | [Resource](ts-types.md#resource) | 否 | 组件SymbolSpan内容。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | 667| symbolSpanStyle<sup>11+</sup> | [RichEditorSymbolSpanStyle](#richeditorsymbolspanstyle11) | 否 | 组件SymbolSpan样式信息。 <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。| 668| paragraphStyle<sup>12+</sup> | [RichEditorParagraphStyle](#richeditorparagraphstyle11) | 否 | 段落样式。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。| 669| previewText<sup>12+</sup> | string | 否 | 文本Span预上屏内容。 <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。| 670 671 672## RichEditorSpanPosition 673 674Span位置信息。 675 676**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 677 678**系统能力:** SystemCapability.ArkUI.ArkUI.Full 679 680| 名称 | 类型 | 必填 | 说明 | 681| --------- | ---------------- | ---- | --------------------------- | 682| spanIndex | number | 是 | Span索引值。 | 683| spanRange | [number, number] | 是 | Span内容在RichEditor内的起始和结束位置。 | 684 685## RichEditorSpanType 686 687Span类型信息。 688 689**系统能力:** SystemCapability.ArkUI.ArkUI.Full 690 691| 名称 | 值 | 说明 | 692| ----- | ---- | ------------ | 693| TEXT | 0 | Span为文字类型。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 | 694| IMAGE | 1 | Span为图像类型。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 | 695| MIXED | 2 | Span为图文混合类型。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 | 696| BUILDER<sup>12+</sup> | 3 | Span为BuilderSpan类型。 <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | 697| DEFAULT<sup>15+</sup> | 4 | 默认类型,不指定Span类型时生效。 <br/>**原子化服务API:** 从API version 15开始,该接口支持在原子化服务中使用。| 698 699## RichEditorResponseType<sup>11+</sup> 700 701菜单的响应类型。 702 703**原子化服务API:** 从API version 15开始,该接口支持在原子化服务中使用。 704 705**系统能力:** SystemCapability.ArkUI.ArkUI.Full 706 707| 名称 | 值 | 说明 | 708| ----- | ---- | ------------ | 709| RIGHT_CLICK | 0 | 通过鼠标右键触发菜单弹出。 | 710| LONG_PRESS | 1 | 通过长按触发菜单弹出。 | 711| SELECT | 2 | 通过鼠标选中触发菜单弹出。 | 712| DEFAULT<sup>15+</sup> | 3 | 默认类型,不指定响应类型时生效。 | 713 714## RichEditorTextStyleResult 715 716后端返回的文本样式信息。 717 718**系统能力:** SystemCapability.ArkUI.ArkUI.Full 719 720| 名称 | 类型 | 必填 | 说明 | 721| ---------- | ---------------------------------------- | ---- | ------------ | 722| fontColor | [ResourceColor](ts-types.md#resourcecolor) | 是 | 文本颜色。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。| 723| fontSize | number | 是 | 字体大小,默认单位为fp。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。| 724| fontStyle | [FontStyle](ts-appendix-enums.md#fontstyle) | 是 | 字体样式。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。| 725| fontWeight | number | 是 | 字体粗细。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。| 726| fontFamily | string | 是 | 字体列表。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。| 727| decoration | [DecorationStyleResult](ts-text-common.md#decorationstyleresult12) | 是 | 文本装饰线样式信息。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。| 728| textShadow<sup>12+</sup> | Array<[ShadowOptions](ts-universal-attributes-image-effect.md#shadowoptions对象说明)> | 否 | 文字阴影效果。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。| 729| lineHeight<sup>12+</sup> | number | 否 | 文本行高,默认单位为fp。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。| 730| letterSpacing<sup>12+</sup>| number | 否 | 文本字符间距,默认单位为fp。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。| 731| fontFeature<sup>12+</sup> | string | 否 | 文字特性效果。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。| 732 733> **说明:** 734> 735> 在RichEditorTextStyle中,fontWeight是设置字体粗细的输入参数。 736> 而在RichEditorTextStyleResult中,会将之前设置的字体粗细转换为数字后返回。 737> 转换关系如下: 738> 739> | RichEditorTextStyle中的fontWeight | RichEditorTextStyleResult中的fontWeight | 740> | ---- | ----------------------------------- | 741> | 100 | 0 | 742> | 200 | 1 | 743> | 300 | 2 | 744> | 400 | 3 | 745> | 500 | 4 | 746> | 600 | 5 | 747> | 700 | 6 | 748> | 800 | 7 | 749> | 900 | 8 | 750> | Lighter | 12 | 751> | Normal | 10 | 752> | Regular | 14 | 753> | Medium | 13 | 754> | Bold | 9 | 755> | Bolder | 11 | 756> 757> RichEditorSymbolSpanStyle和RichEditorSymbolSpanStyleResult中fontWeight的转换关系, 758> 与RichEditorTextStyle和RichEditorTextStyleResult中fontWeight的转换关系一致。 759 760## RichEditorSymbolSpanStyleResult<sup>11+</sup> 761 762后端返回的SymbolSpan样式信息。 763 764**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 765 766**系统能力:** SystemCapability.ArkUI.ArkUI.Full 767 768| 名称 | 类型 | 必填 | 说明 | 769| ------ | -------- | ---- | -------------------------------------- | 770| fontColor | Array\<[ResourceColor](ts-types.md#resourcecolor)\> | 是 | SymbolSpan组件颜色。<br/> 默认值:不同渲染策略下默认值不同。 | 771| fontSize | number \| string \| [Resource](ts-types.md#resource) | 是 | SymbolSpan组件大小,默认单位为fp。<br/>默认值:跟随主题。| 772| fontWeight | number \| [FontWeight](ts-appendix-enums.md#fontweight) \| string | 是 | SymbolSpan组件粗细。<br/>number类型取值[100,900],取值间隔为100,默认为400,取值越大,字体越粗。<br/>string类型仅支持number类型取值的字符串形式,例如“400”,以及“bold”、“bolder”、“lighter”、“regular” 、“medium”分别对应FontWeight中相应的枚举值。<br/>默认值:FontWeight.Normal。| 773| renderingStrategy | [SymbolRenderingStrategy](ts-basic-components-symbolGlyph.md#symbolrenderingstrategy11枚举说明) | 是 | SymbolSpan组件渲染策略。<br/>默认值:SymbolRenderingStrategy.SINGLE。<br/> 774| effectStrategy | [SymbolEffectStrategy](ts-basic-components-symbolGlyph.md#symboleffectstrategy11枚举说明) | 是 | SymbolSpan组件动效策略。<br/>默认值:SymbolEffectStrategy.NONE。<br/> 775 776## RichEditorImageSpanResult 777 778后端返回的图片信息。 779 780**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 781 782**系统能力:** SystemCapability.ArkUI.ArkUI.Full 783 784| 名称 | 类型 | 必填 | 说明 | 785|------------------|-------------------------------------------------------------------|-----|------------------| 786| spanPosition | [RichEditorSpanPosition](#richeditorspanposition) | 是 | Span位置。| 787| valuePixelMap | [PixelMap](../../apis-image-kit/js-apis-image.md#pixelmap7) | 否 | 图片内容。| 788| valueResourceStr | [ResourceStr](ts-types.md#resourcestr) | 否 | 图片资源id。| 789| imageStyle | [RichEditorImageSpanStyleResult](#richeditorimagespanstyleresult) | 是 | 图片样式。| 790| offsetInSpan | [number, number] | 是 | Span里图片的起始和结束位置。| 791 792## RichEditorImageSpanStyleResult 793 794后端返回的图片样式信息。 795 796**系统能力:** SystemCapability.ArkUI.ArkUI.Full 797 798| 名称 | 类型 | 必填 | 说明 | 799| ------------- | ---------------------------------------- | ---- | --------- | 800| size | [number, number] | 是 | 图片的宽度和高度,单位为px。默认值:size的默认值与objectFit的值有关,不同的objectFit值对应的size默认值也不同。objectFit的值为Cover时,图片高度为组件高度减去组件上下内边距,图片宽度为组件宽度减去组件左右内边距。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。| 801| verticalAlign | [ImageSpanAlignment](ts-appendix-enums.md#imagespanalignment10) | 是 | 图片垂直对齐方式。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。| 802| objectFit | [ImageFit](ts-appendix-enums.md#imagefit) | 是 | 图片缩放类型。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。| 803| layoutStyle<sup>12+</sup> | [RichEditorLayoutStyle](#richeditorlayoutstyle11) | 否 | 图片布局风格。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | 804 805## RichEditorLayoutStyle<sup>11+</sup> 806 807**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 808 809**系统能力:** SystemCapability.ArkUI.ArkUI.Full 810 811|名称 |类型 |必填| 说明| 812| ------------- | ----------------------- | ---- | ------------------------------------------------------------ | 813|margin | [Dimension](ts-types.md#dimension10) \| [Margin](ts-types.md#margin) | 否 | 外边距类型,用于描述组件不同方向的外边距。<br/>参数为Dimension类型时,四个方向外边距同时生效。| 814|borderRadius | [Dimension](ts-types.md#dimension10) \| [BorderRadiuses](ts-types.md#borderradiuses9) | 否 | 圆角类型,用于描述组件边框圆角半径。<br/>参数为Dimension类型时,不支持以Percentage形式设置。| 815 816## RichEditorOptions 817 818RichEditor初始化参数。 819 820**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 821 822**系统能力:** SystemCapability.ArkUI.ArkUI.Full 823 824| 名称 | 类型 | 必填 | 说明 | 825| ---------- | ---------------------------------------- | ---- | ------- | 826| controller | [RichEditorController](#richeditorcontroller) | 是 | 富文本控制器。 | 827 828## RichEditorStyledStringOptions<sup>12+</sup> 829 830RichEditor初始化参数。 831 832**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 833 834**系统能力:** SystemCapability.ArkUI.ArkUI.Full 835 836| 名称 | 类型 | 必填 | 说明 | 837| ---------- | ---------------------------------------- | ---- | ------- | 838| controller | [RichEditorStyledStringController](#richeditorstyledstringcontroller12) | 是 | 富文本控制器。 | 839 840## RichEditorChangeValue<sup>12+</sup> 841 842**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 843 844**系统能力:** SystemCapability.ArkUI.ArkUI.Full 845 846| 名称 | 类型 | 必填 | 说明 | 847| --------------------- | ---------------------------------------- | ---- | ------------------- | 848| rangeBefore | [TextRange](ts-text-common.md#textrange12) | 是 | 即将被替换内容的开始和结束索引。 | 849| replacedSpans | Array<[RichEditorTextSpanResult](#richeditortextspanresult)> | 是 | 替换后文本Span的具体信息。 | 850| replacedImageSpans | Array<[RichEditorImageSpanResult](#richeditorimagespanresult)> | 是 | 替换后ImageSpan的具体信息。 | 851| replacedSymbolSpans | Array<[RichEditorTextSpanResult](#richeditortextspanresult)> | 是 | 替换后SymbolSpan的具体信息。 | 852 853## RichEditorBaseController<sup>12+</sup> 854 855RichEditor组件控制器基类。 856 857### getCaretOffset<sup>10+</sup> 858 859getCaretOffset(): number 860 861返回当前光标所在位置。 862 863**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 864 865**系统能力:** SystemCapability.ArkUI.ArkUI.Full 866 867**返回值:** 868 869| 类型 | 说明 | 870| ------ | --------- | 871| number | 当前光标所在位置。 | 872 873### setCaretOffset<sup>10+</sup> 874 875setCaretOffset(offset: number): boolean 876 877设置光标位置。 878 879**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 880 881**系统能力:** SystemCapability.ArkUI.ArkUI.Full 882 883**参数:** 884 885| 参数名 | 类型 | 必填 | 说明 | 886| ------ | ------ | ---- | -------------------- | 887| offset | number | 是 | 光标偏移位置。超出所有内容范围时,设置失败。 | 888 889**返回值:** 890 891| 类型 | 说明 | 892| ------- | --------- | 893| boolean | 光标是否设置成功。 | 894 895### closeSelectionMenu<sup>10+</sup> 896 897closeSelectionMenu(): void 898 899关闭自定义选择菜单或系统默认选择菜单。 900 901**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 902 903**系统能力:** SystemCapability.ArkUI.ArkUI.Full 904 905### getTypingStyle<sup>11+</sup> 906 907getTypingStyle(): RichEditorTextStyle 908 909获得用户预设的样式。 910 911**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 912 913**系统能力:** SystemCapability.ArkUI.ArkUI.Full 914 915**返回值:** 916 917| 类型 | 说明 | 918| ---------------------------------------- | ------- | 919| [RichEditorTextStyle](#richeditortextstyle) | 用户预设样式。 | 920 921### setTypingStyle<sup>11+</sup> 922 923setTypingStyle(value: RichEditorTextStyle): void 924 925设置用户预设的样式。 926 927**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 928 929**系统能力:** SystemCapability.ArkUI.ArkUI.Full 930 931**参数:** 932 933| 参数名 | 类型 | 必填 | 说明 | 934| ----- | ---------------------------------------- | ---- | ----- | 935| value | [RichEditorTextStyle](#richeditortextstyle) | 是 | 预设样式。 | 936 937### setSelection<sup>11+</sup> 938 939setSelection(selectionStart: number, selectionEnd: number, options?: SelectionOptions): void 940 941支持设置组件内的内容选中,选中部分背板高亮。 942 943selectionStart和selectionEnd均为-1时表示全选。 944 945未获焦时调用该接口不产生选中效果。 946 947从API version 12开始,在2in1设备中,无论options取何值,调用setSelection接口都不会弹出菜单,此外,如果组件中已经存在菜单,调用setSelection接口会关闭菜单。 948 949在非2in1设备中,options取值为MenuPolicy.DEFAULT时,遵循以下规则: 950 9511. 组件内有手柄菜单时,接口调用后不关闭菜单,并且调整菜单位置。 952 9532. 组件内有不带手柄的菜单时,接口调用后不关闭菜单,并且菜单位置不变。 954 9553. 组件内无菜单时,接口调用后也无菜单显示。 956 957**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 958 959**系统能力:** SystemCapability.ArkUI.ArkUI.Full 960 961**参数:** 962 963| 参数名 | 类型 | 必填 | 说明 | 964| -------------- | ------ | ---- | ------- | 965| selectionStart | number | 是 | 选中开始位置。 | 966| selectionEnd | number | 是 | 选中结束位置。 | 967| options<sup>12+</sup> | [SelectionOptions](ts-types.md#selectionoptions12对象说明) | 否 | 选择项配置。 | 968 969### isEditing<sup>12+</sup> 970 971isEditing(): boolean 972 973获取当前富文本的编辑状态。 974 975**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 976 977**系统能力:** SystemCapability.ArkUI.ArkUI.Full 978 979**返回值:** 980 981| 类型 | 说明 | 982| ------- | ----------------------------- | 983| boolean | true为编辑态,false为非编辑态。 | 984 985### stopEditing<sup>12+</sup> 986 987stopEditing(): void 988 989退出编辑态。 990 991**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 992 993**系统能力:** SystemCapability.ArkUI.ArkUI.Full 994 995### getLayoutManager<sup>12+</sup> 996 997getLayoutManager(): LayoutManager 998 999获取布局管理器对象。 1000 1001**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1002 1003**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1004 1005**返回值:** 1006 1007| 类型 | 说明 | 1008| ---------------------------------------- | ------- | 1009| [LayoutManager](ts-text-common.md#LayoutManager12) | 布局管理器对象。 | 1010 1011### getPreviewText<sup>12+</sup> 1012 1013getPreviewText(): PreviewText 1014 1015获取预上屏信息。 1016 1017**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1018 1019**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1020 1021**返回值:** 1022 1023| 类型 | 说明 | 1024| ---------------------------------------- | ------- | 1025| [PreviewText](ts-text-common.md#previewtext12) | 预上屏信息。 | 1026 1027## RichEditorController 1028 1029RichEditor组件的控制器,继承自[RichEditorBaseController](#richeditorbasecontroller12)。 1030 1031### 导入对象 1032 1033``` 1034controller: RichEditorController = new RichEditorController() 1035``` 1036 1037### addTextSpan 1038 1039addTextSpan(value: string, options?: RichEditorTextSpanOptions): number 1040 1041添加文本内容,如果组件光标闪烁,插入后光标位置更新为新插入文本的后面。 1042 1043**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 1044 1045**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1046 1047**参数:** 1048 1049| 参数名 | 类型 | 必填 | 说明 | 1050| ------- | ---------------------------------------- | ---- | ----- | 1051| value | string | 是 | 文本内容。 | 1052| options | [RichEditorTextSpanOptions](#richeditortextspanoptions) | 否 | 文本选项。 | 1053 1054**返回值:** 1055 1056| 类型 | 说明 | 1057| ------ | -------------------- | 1058| number | 添加完成的TextSpan所在的位置。 | 1059 1060### addImageSpan 1061 1062addImageSpan(value: PixelMap | ResourceStr, options?: RichEditorImageSpanOptions): number 1063 1064添加图片内容,如果组件光标闪烁,插入后光标位置更新为新插入图片的后面。 1065 1066不建议直接添加网络图片。 1067 1068**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 1069 1070**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1071 1072**参数:** 1073 1074| 参数名 | 类型 | 必填 | 说明 | 1075| ------- | ---------------------------------------- | ---- | ----- | 1076| value | [PixelMap](../../apis-image-kit/js-apis-image.md#pixelmap7)\|[ResourceStr](ts-types.md#resourcestr) | 是 | 图片内容。 | 1077| options | [RichEditorImageSpanOptions](#richeditorimagespanoptions) | 否 | 图片选项。 | 1078 1079**返回值:** 1080 1081| 类型 | 说明 | 1082| ------ | -------------------- | 1083| number | 添加完成的ImageSpan所在的位置。 | 1084 1085### addBuilderSpan<sup>11+</sup> 1086 1087addBuilderSpan(value: CustomBuilder, options?: RichEditorBuilderSpanOptions): number 1088 1089添加用户自定义布局Span。 1090 1091> **说明:** 1092> 1093> - RichEditor组件添加占位Span,占位Span调用系统的measure方法计算真实的长宽和位置。 1094> - 可通过[RichEditorBuilderSpanOptions](#richeditorbuilderspanoptions11)设置此builder在RichEditor中的index(一个文字为一个单位)。 1095> - 此占位Span不可获焦,支持拖拽,支持部分通用属性,占位、删除等能力等同于ImageSpan,长度视为一个文字。 1096> - 支持通过[bindSelectionMenu](#bindselectionmenu)设置自定义菜单。 1097> - 不支持通过[getSpans](#getspans),[getSelection](#getselection11),[onSelect](#onselect),[aboutToDelete](#abouttodelete)获取builderSpan信息。 1098> - 不支持通过[updateSpanStyle](#updatespanstyle),[updateParagraphStyle](#updateparagraphstyle11)等方式更新builder。 1099> - 对此builder节点进行复制或粘贴不生效。 1100> - builder的布局约束由RichEditor传入,如果builder里最外层组件不设置大小,则会用RichEditor的大小作为maxSize。 1101> - builder的手势相关事件机制与通用手势事件相同,如果builder中未设置透传,则仅有builder中的子组件响应。 1102> - 如果组件光标闪烁,插入后光标位置更新为新插入builder的后面。 1103 1104通用属性仅支持[size](ts-universal-attributes-size.md#size)、[padding](ts-universal-attributes-size.md#padding)、[margin](ts-universal-attributes-size.md#margin)、[aspectRatio](ts-universal-attributes-layout-constraints.md#aspectratio)、[borderStyle](ts-universal-attributes-border.md#borderstyle)、[borderWidth](ts-universal-attributes-border.md#borderwidth)、[borderColor](ts-universal-attributes-border.md#bordercolor)、[borderRadius](ts-universal-attributes-border.md#borderradius)、[backgroundColor](ts-universal-attributes-background.md#backgroundcolor)、[backgroundBlurStyle](ts-universal-attributes-background.md#backgroundblurstyle9)、[opacity](ts-universal-attributes-opacity.md)、[blur](ts-universal-attributes-image-effect.md#blur)、[backdropBlur](ts-universal-attributes-background.md#backdropblur)、[shadow](ts-universal-attributes-image-effect.md#shadow)、[grayscale](ts-universal-attributes-image-effect.md#grayscale)、[brightness](ts-universal-attributes-image-effect.md#brightness)、[saturate](ts-universal-attributes-image-effect.md#saturate)、 1105[contrast](ts-universal-attributes-image-effect.md#contrast)、[invert](ts-universal-attributes-image-effect.md#invert)、[sepia](ts-universal-attributes-image-effect.md#sepia)、[hueRotate](ts-universal-attributes-image-effect.md#huerotate)、[colorBlend](ts-universal-attributes-image-effect.md#colorblend7)、[linearGradientBlur](ts-universal-attributes-image-effect.md#lineargradientblur12)、[clip](ts-universal-attributes-sharp-clipping.md#clip)、[mask](ts-universal-attributes-sharp-clipping.md#mask)、[foregroundBlurStyle](ts-universal-attributes-foreground-blur-style.md#foregroundblurstyle)、[accessibilityGroup](ts-universal-attributes-accessibility.md#accessibilitygroup)、[accessibilityText](ts-universal-attributes-accessibility.md#accessibilitytext)、[accessibilityDescription](ts-universal-attributes-accessibility.md#accessibilitydescription)、[accessibilityLevel](ts-universal-attributes-accessibility.md#accessibilitylevel)、[sphericalEffect](ts-universal-attributes-image-effect.md#sphericaleffect12)、[lightUpEffect](ts-universal-attributes-image-effect.md#lightupeffect12)、[pixelStretchEffect](ts-universal-attributes-image-effect.md#pixelstretcheffect12)。 1106 1107**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1108 1109**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1110 1111**参数:** 1112 1113| 参数名 | 类型 | 必填 | 说明 | 1114| ------- | ---------------------------------------- | ---- | ---------- | 1115| value | [CustomBuilder](ts-types.md#custombuilder8) | 是 | 自定义组件。 | 1116| options | [RichEditorBuilderSpanOptions](#richeditorbuilderspanoptions11) | 否 | builder选项。 | 1117 1118**返回值:** 1119 1120| 类型 | 说明 | 1121| ------ | ---------------------- | 1122| number | 添加完成的builderSpan所在的位置。 | 1123 1124### addSymbolSpan<sup>11+</sup> 1125 1126addSymbolSpan(value: Resource, options?: RichEditorSymbolSpanOptions ): number 1127 1128在Richeditor中添加SymbolSpan,如果组件光标闪烁,插入后光标位置更新为新插入Symbol的后面。 1129 1130暂不支持手势、复制、拖拽处理。 1131 1132**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1133 1134**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1135 1136**参数:** 1137 1138| 参数名 | 类型 | 必填 | 说明 | 1139| ------- | ---------------------------------------- | ---- | ----- | 1140| value | [Resource](ts-types.md#resource) | 是 | 组件内容。 | 1141| options | [RichEditorSymbolSpanOptions](#richeditorsymbolspanoptions11) | 否 | 组件选项。 | 1142 1143**返回值:** 1144 1145| 类型 | 说明 | 1146| ------ | --------------------- | 1147| number | 添加完成的SymbolSpan所在的位置。 | 1148 1149### updateSpanStyle 1150 1151updateSpanStyle(value: RichEditorUpdateTextSpanStyleOptions | RichEditorUpdateImageSpanStyleOptions | RichEditorUpdateSymbolSpanStyleOptions): void 1152 1153更新文本、图片或SymbolSpan样式。<br/>若只更新了一个Span的部分内容,则会根据更新部分、未更新部分将该Span拆分为多个Span。 1154 1155使用该接口更新文本、图片或SymbolSpan样式时默认不会关闭自定义文本选择菜单。 1156 1157**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 1158 1159**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1160 1161**参数:** 1162 1163| 参数名 | 类型 | 必填 | 说明 | 1164| ------ | -------- | ---- | -------------------------------------- | 1165| value | [RichEditorUpdateTextSpanStyleOptions](#richeditorupdatetextspanstyleoptions) \| [RichEditorUpdateImageSpanStyleOptions](#richeditorupdateimagespanstyleoptions) \| [RichEditorUpdateSymbolSpanStyleOptions](#richeditorupdatesymbolspanstyleoptions11) | 是 | 文本、图片或SymbolSpan的样式选项信息。 | 1166 1167> **说明:** 1168> 1169> 当start大于end时为异常情况,此时start为0,end为无穷大。 1170 1171### updateParagraphStyle<sup>11+</sup> 1172 1173updateParagraphStyle(value: RichEditorParagraphStyleOptions): void 1174 1175更新段落的样式。 1176 1177**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1178 1179**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1180 1181**参数:** 1182 1183| 参数名 | 类型 | 必填 | 说明 | 1184| ----- | ---------------------------------------- | ---- | ---------- | 1185| value | [RichEditorParagraphStyleOptions](#richeditorparagraphstyleoptions11) | 是 | 段落的样式选项信息。 | 1186 1187### getSpans 1188 1189getSpans(value?: RichEditorRange): Array<RichEditorImageSpanResult| RichEditorTextSpanResult> 1190 1191获取span信息。 1192 1193**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 1194 1195**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1196 1197**参数:** 1198 1199| 参数名 | 类型 | 必填 | 说明 | 1200| ----- | ----------------------------------- | ---- | ----------- | 1201| value | [RichEditorRange](#richeditorrange) | 否 | 需要获取span范围。 | 1202 1203**返回值:** 1204 1205| 类型 | 说明 | 1206| ---------------------------------------- | ------------ | 1207| Array<[RichEditorTextSpanResult](#richeditortextspanresult) \| [RichEditorImageSpanResult](#richeditorimagespanresult)> | 文本和图片Span信息。 | 1208 1209### deleteSpans 1210 1211deleteSpans(value?: RichEditorRange): void 1212 1213删除指定范围内的文本和图片。 1214 1215**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 1216 1217**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1218 1219**参数:** 1220 1221| 参数名 | 类型 | 必填 | 说明 | 1222| ----- | ----------------------------------- | ---- | ------------------- | 1223| value | [RichEditorRange](#richeditorrange) | 否 | 删除范围。省略时,删除所有文本和图片。 | 1224 1225### getParagraphs<sup>11+</sup> 1226 1227getParagraphs(value?: RichEditorRange): Array\<RichEditorParagraphResult> 1228 1229获得指定返回的段落。 1230 1231**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1232 1233**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1234 1235**参数:** 1236 1237| 参数名 | 类型 | 必填 | 说明 | 1238| ----- | ----------------------------------- | ---- | ---------- | 1239| value | [RichEditorRange](#richeditorrange) | 否 | 需要获取段落的范围。 | 1240 1241**返回值:** 1242 1243| 类型 | 说明 | 1244| ---------------------------------------- | -------- | 1245| Array\<[RichEditorParagraphResult](#richeditorparagraphresult11)> | 选中段落的信息。 | 1246 1247### getSelection<sup>11+</sup> 1248 1249getSelection(): RichEditorSelection 1250 1251获取选中内容。如果未选中内容,返回光标所在span信息。 1252 1253**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1254 1255**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1256 1257**返回值:** 1258 1259| 类型 | 说明 | 1260| ---------------------------------------- | ------- | 1261| [RichEditorSelection](#richeditorselection) | 选中内容信息。 | 1262 1263### fromStyledString<sup>12+</sup> 1264 1265fromStyledString(value: StyledString): Array\<RichEditorSpan> 1266 1267将属性字符串转换成span信息。 1268 1269**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1270 1271**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1272 1273**参数:** 1274 1275| 参数名 | 类型 | 必填 | 说明 | 1276| ----- | ----------------------------------- | ---- | ---------- | 1277| value | [StyledString](ts-universal-styled-string.md#styledstring) | 是 | 转换前的属性字符串。 | 1278 1279**返回值:** 1280 1281| 类型 | 说明 | 1282| ---------------------------------------- | ------- | 1283| Array<[RichEditorSpan](#richeditorspan12)> | 文本和图片Span信息。 | 1284 1285**错误码:** 1286 1287以下错误码详细介绍请参考[通用错误码](../../errorcode-universal.md)。 1288 1289| 错误码ID | 错误信息 | 1290| -------- | ------------------------------ | 1291| 401 | The parameter check failed. | 1292 1293### toStyledString<sup>12+</sup> 1294 1295toStyledString(value: RichEditorRange): StyledString 1296 1297将给定范围的组件内容转换成属性字符串。 1298 1299**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1300 1301**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1302 1303**参数:** 1304 1305| 参数名 | 类型 | 必填 | 说明 | 1306| ----- | ----------------------------------- | ---- | ---------- | 1307| value | [RichEditorRange](#richeditorrange) | 是 | 需要获取的范围。 | 1308 1309**返回值:** 1310 1311| 类型 | 说明 | 1312| ---------------------------------------- | -------- | 1313| [StyledString](ts-universal-styled-string.md#styledstring) | 转换后的属性字符串 | 1314 1315**错误码:** 1316 1317以下错误码详细介绍请参考[通用错误码](../../errorcode-universal.md)。 1318 1319| 错误码ID | 错误信息 | 1320| -------- | ------------------------------ | 1321| 401 | The parameter check failed. | 1322 1323 1324## RichEditorStyledStringController<sup>12+</sup> 1325 1326使用属性字符串构建的RichEditor组件的控制器,继承自[RichEditorBaseController](#richeditorbasecontroller12)。 1327 1328### 导入对象 1329 1330``` 1331controller: RichEditorStyledStringController = new RichEditorStyledStringController() 1332``` 1333 1334### getSelection<sup>12+</sup> 1335 1336getSelection(): RichEditorRange 1337 1338获取当前富文本当前的选中区域范围。 1339 1340**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1341 1342**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1343 1344**返回值:** 1345 1346| 类型 | 说明 | 1347| ---------------------------------------- | ------- | 1348| [RichEditorRange](#richeditorrange) | 选中区域范围。 | 1349 1350### setStyledString<sup>12+</sup> 1351 1352setStyledString(styledString: StyledString): void 1353 1354设置富文本组件显示的属性字符串。 1355 1356**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1357 1358**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1359 1360**参数:** 1361 1362| 参数名 | 类型 | 必填 | 说明 | 1363| ----- | ------ | ---- | ------------------- | 1364| styledString | [StyledString](ts-universal-styled-string.md#styledstring) | 是 | 属性字符串。<br/>**说明:** <br/>StyledString的子类[MutableStyledString](ts-universal-styled-string.md#mutablestyledstring)也可以作为入参值。 | 1365 1366### getStyledString<sup>12+</sup> 1367 1368getStyledString(): MutableStyledString; 1369 1370获取富文本组件显示的属性字符串。 1371 1372**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1373 1374**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1375 1376**返回值:** 1377 1378| 类型 | 说明 | 1379| ------- | ----------------------------- | 1380| [MutableStyledString](ts-universal-styled-string.md#mutablestyledstring) | 富文本组件显示的属性字符串 | 1381 1382### onContentChanged<sup>12+</sup> 1383 1384onContentChanged(listener: StyledStringChangedListener): void 1385 1386注册文本内容变化回调,该回调会在后端程序导致文本内容变更时触发。 1387 1388**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1389 1390**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1391 1392**参数:** 1393 1394| 参数名 | 类型 | 必填 | 说明 | 1395| ----- | ------ | ---- | ------------------- | 1396| listener | [StyledStringChangedListener](ts-text-common.md#styledstringchangedlistener12) | 是 | 文本内容变化回调监听器。 | 1397 1398## RichEditorSelection 1399 1400选中内容信息。 1401 1402**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 1403 1404**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1405 1406| 名称 | 类型 | 必填 | 说明 | 1407| --------- | ---------------------------------------- | ---- | ------- | 1408| selection | [number, number] | 是 | 选中范围。 | 1409| spans | Array<[RichEditorTextSpanResult](#richeditortextspanresult)\| [RichEditorImageSpanResult](#richeditorimagespanresult)> | 是 | span信息。 | 1410 1411## RichEditorRange 1412 1413定义RichEditor的范围。 1414 1415**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 1416 1417**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1418 1419| 名称 | 类型 | 必填 | 说明 | 1420| ----- | ------ | ---- | ------------------------------------------------------------ | 1421| start | number | 否 | 需要更新样式的文本起始位置,省略或者设置负值时表示从0开始。 | 1422| end | number | 否 | 需要更新样式的文本结束位置,省略或者超出文本范围时表示无穷大。 | 1423 1424 1425## RichEditorSpanStyleOptions 1426 1427文本样式选项。 1428 1429继承自[RichEditorRange](#richeditorrange)。 1430 1431**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 1432 1433**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1434 1435## RichEditorUpdateTextSpanStyleOptions 1436 1437文本样式选项。 1438 1439继承自[RichEditorSpanStyleOptions](#richeditorspanstyleoptions)。 1440 1441**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 1442 1443**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1444 1445| 名称 | 类型 | 必填 | 说明 | 1446| --------- | ------------------------------------------- | ---- | ---------- | 1447| textStyle | [RichEditorTextStyle](#richeditortextstyle) | 是 | 文本样式。 | 1448 1449## RichEditorUpdateImageSpanStyleOptions 1450 1451图片样式选项。 1452 1453继承自[RichEditorSpanStyleOptions](#richeditorspanstyleoptions)。 1454 1455**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 1456 1457**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1458 1459| 名称 | 类型 | 必填 | 说明 | 1460| ---------- | ---------------------------------------- | ---- | ------------------------------- | 1461| imageStyle | [RichEditorImageSpanStyle](#richeditorimagespanstyle) | 是 | 图片样式。 | 1462 1463## RichEditorUpdateSymbolSpanStyleOptions<sup>11+</sup> 1464 1465SymbolSpan样式选项。 1466 1467继承自[RichEditorSpanStyleOptions](#richeditorspanstyleoptions)。 1468 1469**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1470 1471**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1472 1473| 名称 | 类型 | 必填 | 说明 | 1474| ----------- | --------------------------------------------------------- | ---- | ---------- | 1475| symbolStyle | [RichEditorSymbolSpanStyle](#richeditorsymbolspanstyle11) | 是 | 组件样式。 | 1476 1477## RichEditorParagraphStyleOptions<sup>11+</sup> 1478 1479段落样式选项。 1480 1481继承自[RichEditorSpanStyleOptions](#richeditorspanstyleoptions)。 1482 1483**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1484 1485**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1486 1487| 名称 | 类型 | 必填 | 说明 | 1488| ----- | ---------------------------------------- | ---- | ---------------------------------- | 1489| style | [RichEditorParagraphStyle](#richeditorparagraphstyle11) | 是 | 段落样式。 | 1490 1491> **说明:** 1492> 1493> 接口作用的范围:设定的区间所涉及的段落。 1494 1495 1496## RichEditorParagraphStyle<sup>11+</sup> 1497 1498段落样式。 1499 1500**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1501 1502**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1503 1504| 名称 | 类型 | 必填 | 说明 | 1505| ------------- | ---------------------------------------- | ---- | ------------------ | 1506| textAlign | [TextAlign](ts-appendix-enums.md#textalign) | 否 | 设置文本段落在水平方向的对齐方式。默认值:TextAlign.START <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。| 1507| leadingMargin | [Dimension](ts-types.md#dimension10) \| [LeadingMarginPlaceholder](#leadingmarginplaceholder11) | 否 | 设置文本段落缩进,当段落仅存在ImageSpan或BuilderSpan时,此属性值不生效。参数为Dimension类型时,不支持以Percentage形式设置。默认值:{"size":["0.00px","0.00px"]} <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。| 1508| wordBreak<sup>12+</sup> | [WordBreak](ts-appendix-enums.md#wordbreak11) | 否 | 设置断行规则。 <br />默认值:WordBreak.BREAK_WORD | 1509| lineBreakStrategy<sup>12+</sup> | [LineBreakStrategy](ts-appendix-enums.md#linebreakstrategy12) | 否 | 设置折行规则。 <br />默认值:LineBreakStrategy.GREEDY<br />在wordBreak不等于breakAll的时候生效,不支持连字符。 | 1510 1511## LeadingMarginPlaceholder<sup>11+</sup> 1512 1513前导边距占位符,用于表示文本段落左侧与组件边缘之间的距离。 1514 1515**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1516 1517| 名称 | 类型 | 必填 | 说明 | 1518| -------- | ---------------------------------------- | ---- | -------------- | 1519| pixelMap | [PixelMap](../../apis-image-kit/js-apis-image.md#pixelmap7) | 是 | 图片内容。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。| 1520| size | \[[Dimension](ts-types.md#dimension10), [Dimension](ts-types.md#dimension10)\] | 是 | 图片大小,不支持设置百分比。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | 1521 1522## RichEditorParagraphResult<sup>11+</sup> 1523 1524后端返回的段落信息。 1525 1526**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1527 1528**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1529 1530| 名称 | 类型 | 必填 | 说明 | 1531| ----- | ---------------------------------------- | ---- | ------- | 1532| style | [RichEditorParagraphStyle](#richeditorparagraphstyle11) | 是 | 段落样式。 | 1533| range | \[number, number\] | 是 | 段落起始和结束位置。 | 1534 1535## RichEditorTextSpanOptions 1536 1537添加文本的偏移位置和文本样式信息。 1538 1539**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1540 1541| 名称 | 类型 | 必填 | 说明 | 1542| ---------------------------- | ---------------------------------------- | ---- | -------------------------- | 1543| offset | number | 否 | 添加文本的位置。省略时,添加到所有内容的最后。<br/>当值小于0时,放在所有内容最前面;当值大于所有内容长度时,放在所有内容最后面。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。| 1544| style | [RichEditorTextStyle](#richeditortextstyle) | 否 | 文本样式信息。省略时,使用系统默认文本信息。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。| 1545| paragraphStyle<sup>11+</sup> | [RichEditorParagraphStyle](#richeditorparagraphstyle11) | 否 | 段落样式。 <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | 1546| gesture<sup>11+</sup> | [RichEditorGesture](#richeditorgesture11) | 否 | 行为触发回调。省略时,仅使用系统默认行为。 <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。| 1547 1548## RichEditorTextStyle 1549 1550文本样式信息。 1551 1552**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1553 1554| 名称 | 类型 | 必填 | 说明 | 1555| ------------------------ | ---------------------------------------- | ---- | ---------------------------------------- | 1556| fontColor | [ResourceColor](ts-types.md#resourcecolor) | 否 | 文本颜色。<br/> 默认值:$r('sys.color.font_primary')。<br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。| 1557| fontSize | [Length](ts-types.md#length) \| number | 否 | 设置字体大小,Length为number类型时,使用fp单位。字体默认大小16。不支持设置百分比字符串。字体大小设置为0时,显示默认字体大小。<br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。| 1558| fontStyle | [FontStyle](ts-appendix-enums.md#fontstyle) | 否 | 字体样式。<br/>默认值:FontStyle.Normal。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。| 1559| fontWeight | number \| [FontWeight](ts-appendix-enums.md#fontweight) \| string | 否 | 字体粗细。<br/>number类型取值[100,900],取值间隔为100,默认为400,取值越大,字体越粗。<br/>string类型仅支持number类型取值的字符串形式,例如“400”,以及“bold”、“bolder”、“lighter”、“regular” 、“medium”分别对应FontWeight中相应的枚举值。<br/>默认值:FontWeight.Normal。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。| 1560| fontFamily | [ResourceStr](ts-types.md#resourcestr) | 否 | 设置字体列表。默认字体'HarmonyOS Sans',当前支持'HarmonyOS Sans'字体和[注册自定义字体](../js-apis-font.md)。 <br/>默认字体:'HarmonyOS Sans'。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。| 1561| decoration | [DecorationStyleInterface](ts-universal-styled-string.md#decorationstyleinterface对象说明) | 否 | 设置文本装饰线样式及其颜色。<br/>type默认值:TextDecorationType.None。<br/>color默认值:跟随字体颜色。<br/>style默认值:TextDecorationStyle.SOLID。<br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。| 1562| textShadow<sup>11+</sup> | [ShadowOptions](ts-universal-attributes-image-effect.md#shadowoptions对象说明) \| Array<[ShadowOptions](ts-universal-attributes-image-effect.md#shadowoptions对象说明)> | 否 | 设置文字阴影效果。该接口支持以数组形式入参,实现多重文字阴影。<br/>**说明:**<br/>仅支持设置阴影模糊半径、阴影的颜色、阴影的偏移量。 <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。| 1563| lineHeight<sup>12+</sup> | number \| string \| [Resource](ts-types.md#resource) | 否 |设置文本的文本行高,设置值不大于0时,不限制文本行高,自适应字体大小,number类型时单位为fp,不支持设置百分比字符串。 <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。| 1564| letterSpacing<sup>12+</sup> | number \| string | 否 | 设置文本字符间距,当取值为负值时,文字会发生压缩,负值过小时会将组件内容区大小压缩为0,导致无内容显示,number类型时单位为fp, 不支持设置百分比字符串。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。| 1565| fontFeature<sup>12+</sup> | string | 否 | 设置文字特性效果,比如数字等宽的特性。如果未设置,默认为变宽数字。设置无效字符保持默认。<br/>格式为:normal \| \<feature-tag-value\><br/>\<feature-tag-value\>的格式为:\<string\> \[ \<integer\> \| on \| off ]<br/>\<feature-tag-value\>的个数可以有多个,中间用','隔开。<br/>例如,使用等宽时钟数字的输入格式为:"ss01" on。<br/>Font Feature当前支持的属性见 [fontFeature属性列表](ts-basic-components-text.md#fontfeature12)。<br/>设置 Font Feature 属性,Font Feature 是 OpenType 字体的高级排版能力,如支持连字、数字等宽等特性,一般用在自定义字体中,其能力需要字体本身支持。<br/>更多 Font Feature 能力介绍可参考 https://www.w3.org/TR/css-fonts-3/#font-feature-settings-prop 和 https://sparanoid.com/lab/opentype-features/<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。| 1566 1567## PlaceholderStyle<sup>12+</sup> 1568 1569添加提示文本的字体样式。 1570 1571**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1572 1573**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1574 1575| 名称 | 类型 | 必填 | 说明 | 1576| ---------------------------- | ---------------------------------------- | ---- | -------------------------- | 1577| font | [Font](ts-types.md#font) | 否 | 设置placeholder文本样式。<br/>默认值跟随主题。| 1578| fontColor | [ResourceColor](ts-types.md#resourcecolor) | 否 | 设置placeholder文本颜色。<br/>默认值跟随主题。| 1579 1580## RichEditorImageSpanOptions 1581 1582添加图片的偏移位置和图片样式信息。 1583 1584**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1585 1586| 名称 | 类型 | 必填 | 说明 | 1587| --------------------- | ---------------------------------------- | ---- | -------------------------- | 1588| offset | number | 否 | 添加图片的位置。省略时,添加到所有内容的最后。<br/>当值小于0时,放在所有内容最前面;当值大于所有内容长度时,放在所有内容最后面。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。| 1589| imageStyle | [RichEditorImageSpanStyle](#richeditorimagespanstyle) | 否 | 图片样式信息。省略时,使用系统默认图片信息。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。| 1590| gesture<sup>11+</sup> | [RichEditorGesture](#richeditorgesture11) | 否 | 行为触发回调。省略时,仅使用系统默认行为。 <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。| 1591| onHover<sup>14+</sup> | [OnHoverCallback](#onhovercallback14) | 否 | 鼠标悬停触发回调。省略时,不执行相关行为。 <br/>**原子化服务API:** 从API version 14开始,该接口支持在原子化服务中使用。| 1592 1593## RichEditorImageSpanStyle 1594 1595图片样式。 1596 1597**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1598 1599| 名称 | 类型 | 必填 | 说明 | 1600| ------------------------- | ---------------------------------------- | ---- | ---------------------------------------- | 1601| size | [[Dimension](ts-types.md#dimension10), [Dimension](ts-types.md#dimension10)] | 否 | 图片宽度和高度。默认值:size的默认值与objectFit的值有关,不同的objectFit值对应的size默认值也不同。objectFit的值为Cover时,图片高度为组件高度减去组件上下内边距,图片宽度为组件宽度减去组件左右内边距。不支持以Percentage形式设置。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 | 1602| verticalAlign | [ImageSpanAlignment](ts-appendix-enums.md#imagespanalignment10)| 否 | 图片垂直对齐方式。<br/>默认值:ImageSpanAlignment.BOTTOM <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。| 1603| objectFit | [ImageFit](ts-appendix-enums.md#imagefit) | 否 | 图片缩放类型。<br/> 默认值:ImageFit.Cover。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 | 1604| layoutStyle<sup>11+</sup> | [RichEditorLayoutStyle](#richeditorlayoutstyle11) | 否 | 图片布局风格。默认值:{"borderRadius":"","margin":""}<br/> <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | 1605 1606## RichEditorSymbolSpanOptions<sup>11+</sup> 1607 1608添加SymbolSpan组件的偏移位置和SymbolSpan组件样式信息。 1609 1610**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1611 1612**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1613 1614| 名称 | 类型 | 必填 | 说明 | 1615| ------ | ---------------------------------------- | ---- | -------------------------- | 1616| offset | number | 否 | 添加组件的位置。省略时,添加到所有内容的最后。<br/>当值小于0时,放在所有内容最前面;当值大于所有内容长度时,放在所有内容最后面。 | 1617| style | [RichEditorSymbolSpanStyle](#richeditorsymbolspanstyle11) | 否 | 组件样式信息。省略时,使用系统默认样式信息。 | 1618 1619## RichEditorSymbolSpanStyle<sup>11+</sup> 1620 1621组件SymbolSpan样式信息。 1622 1623**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1624 1625**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1626 1627| 名称 | 类型 | 必填 | 说明 | 1628| ------ | -------- | ---- | -------------------------------------- | 1629| fontColor | Array\<[ResourceColor](ts-types.md#resourcecolor)\> | 否 | 设置SymbolSpan组件颜色。<br/> 默认值:不同渲染策略下默认值不同。 | 1630| fontSize | number \| string \| [Resource](ts-types.md#resource) | 否 | 设置SymbolSpan组件大小,默认单位为fp。<br/>默认值:跟随主题。 | 1631| fontWeight | number \| [FontWeight](ts-appendix-enums.md#fontweight) \| string | 否 | 设置SymbolSpan组件粗细。<br/>number类型取值[100,900],取值间隔为100,默认为400,取值越大,字体越粗。<br/>string类型仅支持number类型取值的字符串形式,例如“400”,以及“bold”、“bolder”、“lighter”、“regular” 、“medium”分别对应FontWeight中相应的枚举值。<br/>默认值:FontWeight.Normal。 | 1632| renderingStrategy | [SymbolRenderingStrategy](ts-basic-components-symbolGlyph.md#symbolrenderingstrategy11枚举说明) | 否 | 设置SymbolSpan组件渲染策略。<br/>默认值:SymbolRenderingStrategy.SINGLE。 | 1633| effectStrategy | [SymbolEffectStrategy](ts-basic-components-symbolGlyph.md#symboleffectstrategy11枚举说明) | 否 | 设置SymbolSpan组件动效策略。<br/>默认值:SymbolEffectStrategy.NONE。 | 1634 1635## RichEditorBuilderSpanOptions<sup>11+</sup> 1636 1637添加builder的偏移位置和builder样式信息。 1638 1639**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1640 1641**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1642 1643| 名称 | 类型 | 必填 | 说明 | 1644| ------ | ------ | ---- | ------------------------------------- | 1645| offset | number | 否 | 添加builder的位置。省略或者为异常值时,添加到所有内容的最后。 | 1646 1647## RichEditorSpan<sup>12+</sup> 1648 1649type RichEditorSpan = RichEditorImageSpanResult | RichEditorTextSpanResult 1650 1651RichEditor span信息。 1652 1653**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1654 1655**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1656 1657| 类型 | 说明 | 1658| ------ | ---------- | 1659| [RichEditorImageSpanResult](#richeditorimagespanresult) | 后端返回的图片信息。 | 1660| [RichEditorTextSpanResult](#richeditortextspanresult) | 后端返回的文本样式信息。 | 1661 1662## SelectionMenuOptions<sup>10+</sup> 1663 1664菜单的选项。 1665 1666**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1667 1668| 名称 | 类型 | 必填 | 说明 | 1669| ----------- | ---------- | ---- | ------------- | 1670| onAppear | [MenuOnAppearCallback](#menuonappearcallback12) | 否 | 自定义选择菜单弹出时回调。<br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 | 1671| onDisappear | Callback\<void\> | 否 | 自定义选择菜单关闭时回调。<br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 | 1672| menuType<sup>13+</sup> | [MenuType](ts-text-common.md#menutype13枚举说明) | 否 | 自定义选择菜单类型。<br/>**原子化服务API:** 从API version 13开始,该接口支持在原子化服务中使用。<br/>默认值:MenuType.SELECTION_MENU。 | 1673| onMenuShow<sup>15+</sup> | [MenuCallback](#menucallback15) | 否 | 自定义选择菜单显示时回调。<br/>**原子化服务API:** 从API version 15开始,该接口支持在原子化服务中使用。 | 1674| onMenuHide<sup>15+</sup> | [MenuCallback](#menucallback15) | 否 | 自定义选择菜单隐藏时回调。<br/>**原子化服务API:** 从API version 15开始,该接口支持在原子化服务中使用。 | 1675 1676## PasteEvent<sup>11+</sup> 1677 1678定义用户粘贴事件。 1679 1680**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 1681 1682**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1683 1684| 名称 | 类型 | 必填 | 说明 | 1685| -------------- | ----------- | ---- | ----------------------------- | 1686| preventDefault | Callback\<void\> | 否 | 阻止系统默认粘贴事件。 | 1687 1688## CutEvent<sup>12+</sup> 1689 1690定义用户剪切事件。 1691 1692**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1693 1694**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1695 1696| 名称 | 类型 | 必填 | 说明 | 1697| -------------- | ----------- | ---- | ----------------------------- | 1698| preventDefault | Callback\<void\> | 否 | 阻止系统默认剪切事件。 | 1699 1700## CopyEvent<sup>12+</sup> 1701 1702定义用户拷贝事件。 1703 1704**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1705 1706**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1707 1708| 名称 | 类型 | 必填 | 说明 | 1709| -------------- | ----------- | ---- | ----------------------------- | 1710| preventDefault | Callback\<void\> | 否 | 阻止系统默认拷贝事件。 | 1711 1712## RichEditorGesture<sup>11+</sup> 1713 1714用户行为回调。 1715 1716**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1717 1718**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1719 1720| 名称 | 类型 | 必填 | 说明 | 1721| ----------- | ---------- | ---- | ------------- | 1722| onClick | Callback\<[ClickEvent](ts-universal-events-click.md#clickevent对象说明)\> | 否 | [ClickEvent](ts-universal-events-click.md#clickevent对象说明)为用户点击事件。<br/>点击完成时回调事件。<br/>双击时,第一次点击触发回调事件。| 1723| onLongPress | Callback\<[GestureEvent](ts-gesture-settings.md#gestureevent对象说明)\> | 否 | [GestureEvent](ts-gesture-settings.md#gestureevent对象说明)为用户长按事件。<br/>长按完成时回调事件。 | 1724 1725## KeyboardOptions<sup>12+</sup> 1726 1727设置自定义键盘是否支持避让功能。 1728 1729**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1730 1731**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1732 1733| 名称 | 类型 | 必填 | 说明 | 1734| --------------- | --------------- |---- | ------------------------------------ | 1735| supportAvoidance | boolean | 否 | 设置自定义键盘是否支持避让功能;默认值为false不支持避让,true为支持避让。 | 1736 1737## SubmitCallback<sup>12+</sup> 1738 1739type SubmitCallback = (enterKey: EnterKeyType, event: SubmitEvent) => void 1740 1741软键盘按下回车键时的回调事件。 1742 1743**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1744 1745**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1746 1747**参数:** 1748 1749| 参数名 | 类型 | 必填 | 说明 | 1750| -------- | ------------------------------------------------------------ | ---- | -------------------------------------------------------- | 1751| enterKey | [EnterKeyType](ts-basic-components-textinput.md#enterkeytype枚举说明) | 是 | 软键盘输入法回车键类型。具体类型见EnterKeyType枚举说明。 | 1752| event | [SubmitEvent](ts-basic-components-textinput.md#submitevent11) | 是 | 当提交的时候,提供保持RichEditor编辑状态的方法。EnterKeyType指定为NEW_LINE时,默认保持编辑态。 | 1753 1754## MenuOnAppearCallback<sup>12+</sup> 1755 1756type MenuOnAppearCallback = (start: number, end: number) => void 1757 1758自定义选择菜单弹出时触发的回调事件。 1759 1760**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1761 1762**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1763 1764**参数:** 1765 1766| 参数名 | 类型 | 必填 | 说明 | 1767| -------- | ------------------------------------------------ | ---- | -------------------------------------------------------- | 1768| start | number | 是 | 选中内容的起始位置。 | 1769| end | number | 是 | 选中内容的终止位置。 | 1770 1771## MenuCallback<sup>15+</sup> 1772 1773type MenuCallback = (start: number, end: number) => void 1774 1775自定义选择菜单显示或隐藏时触发的回调事件。 1776 1777**原子化服务API:** 从API version 15开始,该接口支持在原子化服务中使用。 1778 1779**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1780 1781**参数:** 1782 1783| 参数名 | 类型 | 必填 | 说明 | 1784| -------- | ------------------------------------------------ | ---- | -------------------------------------------------------- | 1785| start | number | 是 | 选中内容的起始位置。 | 1786| end | number | 是 | 选中内容的终止位置。 | 1787 1788## PasteEventCallback<sup>12+</sup> 1789 1790type PasteEventCallback = (event?: PasteEvent) => void 1791 1792完成粘贴前,触发回调。 1793 1794**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1795 1796**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1797 1798**参数:** 1799 1800| 参数名 | 类型 | 必填 | 说明 | 1801| -------- | ------------------------------------------------ | ---- | -------------------------------------------------------- | 1802| event | [PasteEvent](#pasteevent11) | 否 | 定义用户粘贴事件。 | 1803 1804## OnHoverCallback<sup>14+</sup> 1805 1806type OnHoverCallback = (status: boolean, event: HoverEvent) => void 1807 1808鼠标悬浮触发回调。 1809 1810**原子化服务API:** 从API version 14开始,该接口支持在原子化服务中使用。 1811 1812**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1813 1814**参数:** 1815 1816| 参数名 | 类型 | 必填 | 说明 | 1817| -------- | ------------------------------------------------ | ---- | -------------------------------------------------------- | 1818| status | boolean | 是 | 表示鼠标是否悬浮在组件上,鼠标进入组件时为true,离开组件时为false。| 1819| event | [HoverEvent](ts-universal-events-hover.md#hoverevent10对象说明) | 是 | 设置阻塞事件冒泡属性。 | 1820 1821## RichEditorTextSpan 1822 1823文本Span信息。 1824 1825**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 1826 1827**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1828 1829| 名称 | 类型 | 必填 | 说明 | 1830| ----------------------------- | ---------------------------------------- | ---- | ---------------------- | 1831| spanPosition | [RichEditorSpanPosition](#richeditorspanposition) | 是 | Span位置。| 1832| value | string | 是 | 文本Span内容。| 1833| textStyle | [RichEditorTextStyle](#richeditortextstyle) | 否 | 文本Span样式信息。| 1834 1835## RichEditorImageSpan 1836 1837图片Span信息。 1838 1839**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 1840 1841**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1842 1843| 名称 | 类型 | 必填 | 说明 | 1844|------------------|-------------------------------------------------------------------|-----|------------------| 1845| spanPosition | [RichEditorSpanPosition](#richeditorspanposition) | 是 | Span位置。| 1846| value | [PixelMap](../../apis-image-kit/js-apis-image.md#pixelmap7)\|[ResourceStr](ts-types.md#resourcestr) | 是 | 图片内容。| 1847| imageStyle | [RichEditorImageSpanStyle](#richeditorimagespanstyle) | 否 | 图片样式。| 1848 1849## 示例 1850 1851### 示例1(更新文本样式) 1852通过[updateSpanStyle](#updatespanstyle)接口更新已有文本样式,更改样式后,使用[getSpans](#getspans)获取文本新的样式信息。 1853 1854```ts 1855// xxx.ets 1856@Entry 1857@Component 1858struct Index { 1859 controller: RichEditorController = new RichEditorController(); 1860 options: RichEditorOptions = { controller: this.controller }; 1861 private start: number = -1; 1862 private end: number = -1; 1863 @State message: string = "[-1, -1]" 1864 @State content: string = "" 1865 1866 build() { 1867 Column() { 1868 Column() { 1869 Text("selection range:").width("100%") 1870 Text() { 1871 Span(this.message) 1872 }.width("100%") 1873 Text("selection content:").width("100%") 1874 Text() { 1875 Span(this.content) 1876 }.width("100%") 1877 } 1878 .borderWidth(1) 1879 .borderColor(Color.Red) 1880 .width("100%") 1881 .height("20%") 1882 1883 Row() { 1884 Button("更新样式:加粗").onClick(() => { 1885 this.controller.updateSpanStyle({ 1886 start: this.start, 1887 end: this.end, 1888 textStyle: 1889 { 1890 fontWeight: FontWeight.Bolder 1891 } 1892 }) 1893 }) 1894 Button("获取选择内容").onClick(() => { 1895 this.content = ""; 1896 this.controller.getSpans({ 1897 start: this.start, 1898 end: this.end 1899 }).forEach(item => { 1900 if(typeof(item as RichEditorImageSpanResult)['imageStyle'] != 'undefined'){ 1901 this.content += (item as RichEditorImageSpanResult).valueResourceStr; 1902 this.content += "\n" 1903 } else { 1904 if(typeof(item as RichEditorTextSpanResult)['symbolSpanStyle'] != 'undefined') { 1905 this.content += (item as RichEditorTextSpanResult).symbolSpanStyle?.fontSize; 1906 this.content += "\n" 1907 }else { 1908 this.content += (item as RichEditorTextSpanResult).value; 1909 this.content += "\n" 1910 } 1911 } 1912 }) 1913 }) 1914 Button("删除选择内容").onClick(() => { 1915 this.controller.deleteSpans({ 1916 start: this.start, 1917 end: this.end 1918 }) 1919 this.start = -1; 1920 this.end = -1; 1921 this.message = "[" + this.start + ", " + this.end + "]" 1922 }) 1923 } 1924 .borderWidth(1) 1925 .borderColor(Color.Red) 1926 .width("100%") 1927 .height("10%") 1928 1929 Column() { 1930 RichEditor(this.options) 1931 .onReady(() => { 1932 this.controller.addTextSpan("012345", 1933 { 1934 style: 1935 { 1936 fontColor: Color.Orange, 1937 fontSize: 30 1938 } 1939 }) 1940 this.controller.addSymbolSpan($r("sys.symbol.ohos_trash"), 1941 { 1942 style: 1943 { 1944 fontSize: 30 1945 } 1946 }) 1947 this.controller.addImageSpan($r("app.media.icon"), 1948 { 1949 imageStyle: 1950 { 1951 size: ["57px", "57px"] 1952 } 1953 }) 1954 this.controller.addTextSpan("56789", 1955 { 1956 style: 1957 { 1958 fontColor: Color.Black, 1959 fontSize: 30 1960 } 1961 }) 1962 }) 1963 .onSelect((value: RichEditorSelection) => { 1964 this.start = value.selection[0]; 1965 this.end = value.selection[1]; 1966 this.message = "[" + this.start + ", " + this.end + "]" 1967 }) 1968 .aboutToIMEInput((value: RichEditorInsertValue) => { 1969 console.log("---------------------- aboutToIMEInput ----------------------") 1970 console.log("insertOffset:" + value.insertOffset) 1971 console.log("insertValue:" + value.insertValue) 1972 return true; 1973 }) 1974 .onIMEInputComplete((value: RichEditorTextSpanResult) => { 1975 console.log("---------------------- onIMEInputComplete ---------------------") 1976 console.log("spanIndex:" + value.spanPosition.spanIndex) 1977 console.log("spanRange:[" + value.spanPosition.spanRange[0] + "," + value.spanPosition.spanRange[1] + "]") 1978 console.log("offsetInSpan:[" + value.offsetInSpan[0] + "," + value.offsetInSpan[1] + "]") 1979 console.log("value:" + value.value) 1980 }) 1981 .aboutToDelete((value: RichEditorDeleteValue) => { 1982 console.log("---------------------- aboutToDelete --------------------------") 1983 console.log("offset:" + value.offset) 1984 console.log("direction:" + value.direction) 1985 console.log("length:" + value.length) 1986 value.richEditorDeleteSpans.forEach(item => { 1987 console.log("---------------------- item --------------------------") 1988 console.log("spanIndex:" + item.spanPosition.spanIndex) 1989 console.log("spanRange:[" + item.spanPosition.spanRange[0] + "," + item.spanPosition.spanRange[1] + "]") 1990 console.log("offsetInSpan:[" + item.offsetInSpan[0] + "," + item.offsetInSpan[1] + "]") 1991 if (typeof(item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { 1992 console.log("image:" + (item as RichEditorImageSpanResult).valueResourceStr) 1993 } else { 1994 console.log("text:" + (item as RichEditorTextSpanResult).value) 1995 } 1996 }) 1997 return true; 1998 }) 1999 .onDeleteComplete(() => { 2000 console.log("---------------------- onDeleteComplete ------------------------") 2001 }) 2002 .placeholder("input...", { 2003 fontColor: Color.Gray, 2004 font: { 2005 size: 16, 2006 weight: FontWeight.Normal, 2007 family: "HarmonyOS Sans", 2008 style: FontStyle.Normal 2009 } 2010 }) 2011 .borderWidth(1) 2012 .borderColor(Color.Green) 2013 .width("100%") 2014 .height("30%") 2015 } 2016 .borderWidth(1) 2017 .borderColor(Color.Red) 2018 .width("100%") 2019 .height("70%") 2020 } 2021 } 2022} 2023``` 2024 2025 2026### 示例2(绑定自定义键盘) 2027通过[customKeyboard](#customkeyboard)给组件绑定自定义键盘。 2028 2029```ts 2030// xxx.ets 2031@Entry 2032@Component 2033struct RichEditorExample { 2034 controller: RichEditorController = new RichEditorController() 2035 2036 // 自定义键盘组件 2037 @Builder CustomKeyboardBuilder() { 2038 Column() { 2039 Grid() { 2040 ForEach([1, 2, 3, 4, 5, 6, 7, 8, 9, '*', 0, '#'], (item: number | string) => { 2041 GridItem() { 2042 Button(item + "") 2043 .width(110).onClick(() => { 2044 this.controller.addTextSpan(item + '', { 2045 offset: this.controller.getCaretOffset(), 2046 style: 2047 { 2048 fontColor: Color.Orange, 2049 fontSize: 30 2050 } 2051 }) 2052 this.controller.setCaretOffset(this.controller.getCaretOffset() + item.toString().length) 2053 }) 2054 } 2055 }) 2056 }.maxCount(3).columnsGap(10).rowsGap(10).padding(5) 2057 }.backgroundColor(Color.Gray) 2058 } 2059 2060 build() { 2061 Column() { 2062 RichEditor({ controller: this.controller }) 2063 // 绑定自定义键盘 2064 .customKeyboard(this.CustomKeyboardBuilder()).margin(10).border({ width: 1 }) 2065 .height(200) 2066 .borderWidth(1) 2067 .borderColor(Color.Red) 2068 .width("100%") 2069 } 2070 } 2071} 2072``` 2073 2074 2075 2076### 示例3(绑定自定义菜单) 2077通过[bindSelectionMenu](#bindselectionmenu)给组件绑定自定义菜单。 2078 2079```ts 2080// xxx.ets 2081import { BusinessError, pasteboard } from '@kit.BasicServicesKit'; 2082 2083export interface SelectionMenuTheme { 2084 imageSize: number; 2085 buttonSize: number; 2086 menuSpacing: number; 2087 editorOptionMargin: number; 2088 expandedOptionPadding: number; 2089 defaultMenuWidth: number; 2090 imageFillColor: Resource; 2091 backGroundColor: Resource; 2092 iconBorderRadius: Resource; 2093 containerBorderRadius: Resource; 2094 cutIcon: Resource; 2095 copyIcon: Resource; 2096 pasteIcon: Resource; 2097 selectAllIcon: Resource; 2098 shareIcon: Resource; 2099 translateIcon: Resource; 2100 searchIcon: Resource; 2101 arrowDownIcon: Resource; 2102 iconPanelShadowStyle: ShadowStyle; 2103 iconFocusBorderColor: Resource; 2104} 2105 2106export const defaultTheme: SelectionMenuTheme = { 2107 imageSize: 24, 2108 buttonSize: 48, 2109 menuSpacing: 8, 2110 editorOptionMargin: 1, 2111 expandedOptionPadding: 3, 2112 defaultMenuWidth: 256, 2113 imageFillColor: $r('sys.color.ohos_id_color_primary'), 2114 backGroundColor: $r('sys.color.ohos_id_color_dialog_bg'), 2115 iconBorderRadius: $r('sys.float.ohos_id_corner_radius_default_m'), 2116 containerBorderRadius: $r('sys.float.ohos_id_corner_radius_card'), 2117 cutIcon: $r("sys.media.ohos_ic_public_cut"), 2118 copyIcon: $r("sys.media.ohos_ic_public_copy"), 2119 pasteIcon: $r("sys.media.ohos_ic_public_paste"), 2120 selectAllIcon: $r("sys.media.ohos_ic_public_select_all"), 2121 shareIcon: $r("sys.media.ohos_ic_public_share"), 2122 translateIcon: $r("sys.media.ohos_ic_public_translate_c2e"), 2123 searchIcon: $r("sys.media.ohos_ic_public_search_filled"), 2124 arrowDownIcon: $r("sys.media.ohos_ic_public_arrow_down"), 2125 iconPanelShadowStyle: ShadowStyle.OUTER_DEFAULT_MD, 2126 iconFocusBorderColor: $r('sys.color.ohos_id_color_focused_outline'), 2127} 2128 2129@Entry 2130@Component 2131struct SelectionMenu { 2132 @State message: string = 'Hello World' 2133 @State textSize: number = 40 2134 @State sliderShow: boolean = false 2135 @State start: number = -1 2136 @State end: number = -1 2137 @State colorTransparent: Color = Color.Transparent 2138 controller: RichEditorController = new RichEditorController(); 2139 options: RichEditorOptions = { controller: this.controller } 2140 private iconArr: Array<Resource> = 2141 [$r('app.media.icon'), $r("app.media.icon"), $r('app.media.icon'), 2142 $r("app.media.icon"), $r('app.media.icon')] 2143 @State iconBgColor: ResourceColor[] = new Array(this.iconArr.length).fill(this.colorTransparent) 2144 @State pasteEnable: boolean = false 2145 @State visibilityValue: Visibility = Visibility.Visible 2146 @State textStyle: RichEditorTextStyle = {} 2147 private fontWeightTable: string[] = ["100", "200", "300", "400", "500", "600", "700", "800", "900", "bold", "normal", "bolder", "lighter", "medium", "regular"] 2148 private theme: SelectionMenuTheme = defaultTheme; 2149 2150 aboutToAppear() { 2151 if (this.controller) { 2152 let richEditorSelection = this.controller.getSelection() 2153 if (richEditorSelection) { 2154 let start = richEditorSelection.selection[0] 2155 let end = richEditorSelection.selection[1] 2156 if (start === 0 && this.controller.getSpans({ start: end + 1, end: end + 1 }).length === 0) { 2157 this.visibilityValue = Visibility.None 2158 } else { 2159 this.visibilityValue = Visibility.Visible 2160 } 2161 } 2162 } 2163 let sysBoard = pasteboard.getSystemPasteboard() 2164 if (sysBoard && sysBoard.hasDataSync()) { 2165 this.pasteEnable = true 2166 } else { 2167 this.pasteEnable = false 2168 } 2169 } 2170 2171 build() { 2172 Column() { 2173 Column() { 2174 RichEditor(this.options) 2175 .onReady(() => { 2176 this.controller.addTextSpan(this.message, { style: { fontColor: Color.Orange, fontSize: 30 } }) 2177 }) 2178 .onSelect((value: RichEditorSelection) => { 2179 if (value.selection[0] == -1 && value.selection[1] == -1) { 2180 return 2181 } 2182 this.start = value.selection[0] 2183 this.end = value.selection[1] 2184 }) 2185 .bindSelectionMenu(RichEditorSpanType.TEXT, this.panel, ResponseType.LongPress, { onDisappear: () => { 2186 this.sliderShow = false 2187 }}) 2188 .bindSelectionMenu(RichEditorSpanType.TEXT, this.panel, ResponseType.RightClick, { onDisappear: () => { 2189 this.sliderShow = false 2190 }}) 2191 .borderWidth(1) 2192 .borderColor(Color.Red) 2193 .width(200) 2194 .height(200) 2195 }.width('100%').backgroundColor(Color.White) 2196 }.height('100%') 2197 } 2198 2199 PushDataToPasteboard(richEditorSelection: RichEditorSelection) { 2200 let sysBoard = pasteboard.getSystemPasteboard() 2201 let pasteData = pasteboard.createData(pasteboard.MIMETYPE_TEXT_PLAIN, '') 2202 if (richEditorSelection.spans && richEditorSelection.spans.length > 0) { 2203 let count = richEditorSelection.spans.length 2204 for (let i = count - 1; i >= 0; i--) { 2205 let item = richEditorSelection.spans[i] 2206 if ((item as RichEditorTextSpanResult)?.textStyle) { 2207 let span = item as RichEditorTextSpanResult 2208 let style = span.textStyle 2209 let data = pasteboard.createRecord(pasteboard.MIMETYPE_TEXT_PLAIN, span.value.substring(span.offsetInSpan[0], span.offsetInSpan[1])) 2210 let prop = pasteData.getProperty() 2211 let temp: Record<string, Object> = { 2212 'color': style.fontColor, 2213 'size': style.fontSize, 2214 'style': style.fontStyle, 2215 'weight': this.fontWeightTable[style.fontWeight], 2216 'fontFamily': style.fontFamily, 2217 'decorationType': style.decoration.type, 2218 'decorationColor': style.decoration.color 2219 } 2220 prop.additions[i] = temp; 2221 pasteData.addRecord(data) 2222 pasteData.setProperty(prop) 2223 } 2224 } 2225 } 2226 sysBoard.clearData() 2227 sysBoard.setData(pasteData).then(() => { 2228 console.info('SelectionMenu copy option, Succeeded in setting PasteData.'); 2229 this.pasteEnable = true; 2230 }).catch((err: BusinessError) => { 2231 console.error('SelectionMenu copy option, Failed to set PasteData. Cause:' + err.message); 2232 }) 2233 } 2234 2235 PopDataFromPasteboard(richEditorSelection: RichEditorSelection) { 2236 let start = richEditorSelection.selection[0] 2237 let end = richEditorSelection.selection[1] 2238 if (start == end && this.controller) { 2239 start = this.controller.getCaretOffset() 2240 end = this.controller.getCaretOffset() 2241 } 2242 let moveOffset = 0 2243 let sysBoard = pasteboard.getSystemPasteboard() 2244 sysBoard.getData((err, data) => { 2245 if (err) { 2246 return 2247 } 2248 let count = data.getRecordCount() 2249 for (let i = 0; i < count; i++) { 2250 const element = data.getRecord(i); 2251 let tex: RichEditorTextStyle = { 2252 fontSize: 16, 2253 fontColor: Color.Black, 2254 fontWeight: FontWeight.Normal, 2255 fontFamily: "HarmonyOS Sans", 2256 fontStyle: FontStyle.Normal, 2257 decoration: { type: TextDecorationType.None, color: "#FF000000", style: TextDecorationStyle.SOLID } 2258 } 2259 if (data.getProperty() && data.getProperty().additions[i]) { 2260 const tmp = data.getProperty().additions[i] as Record<string, Object | undefined>; 2261 if (tmp.color) { 2262 tex.fontColor = tmp.color as ResourceColor; 2263 } 2264 if (tmp.size) { 2265 tex.fontSize = tmp.size as Length | number; 2266 } 2267 if (tmp.style) { 2268 tex.fontStyle = tmp.style as FontStyle; 2269 } 2270 if (tmp.weight) { 2271 tex.fontWeight = tmp.weight as number | FontWeight | string; 2272 } 2273 if (tmp.fontFamily) { 2274 tex.fontFamily = tmp.fontFamily as ResourceStr; 2275 } 2276 if (tmp.decorationType && tex.decoration) { 2277 tex.decoration.type = tmp.decorationType as TextDecorationType; 2278 } 2279 if (tmp.decorationColor && tex.decoration) { 2280 tex.decoration.color = tmp.decorationColor as ResourceColor; 2281 } 2282 if (tex.decoration) { 2283 tex.decoration = { type: tex.decoration.type, color: tex.decoration.color } 2284 } 2285 } 2286 if (element && element.plainText && element.mimeType === pasteboard.MIMETYPE_TEXT_PLAIN && this.controller) { 2287 this.controller.addTextSpan(element.plainText, 2288 { 2289 style: tex, 2290 offset: start + moveOffset 2291 } 2292 ) 2293 moveOffset += element.plainText.length 2294 } 2295 } 2296 if (this.controller) { 2297 this.controller.setCaretOffset(start + moveOffset) 2298 this.controller.closeSelectionMenu() 2299 } 2300 if (start != end && this.controller) { 2301 this.controller.deleteSpans({ start: start + moveOffset, end: end + moveOffset }) 2302 } 2303 }) 2304 } 2305 2306 @Builder 2307 panel() { 2308 Column() { 2309 this.iconPanel() 2310 if (!this.sliderShow) { 2311 this.SystemMenu() 2312 } else { 2313 this.sliderPanel() 2314 } 2315 }.width(256) 2316 } 2317 2318 @Builder iconPanel() { 2319 Column() { 2320 Row({ space: 2 }) { 2321 ForEach(this.iconArr, (item:Resource, index ?: number) => { 2322 Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) { 2323 Image(item).fillColor(this.theme.imageFillColor).width(24).height(24).focusable(true).draggable(false) 2324 } 2325 .borderRadius(this.theme.iconBorderRadius) 2326 .width(this.theme.buttonSize) 2327 .height(this.theme.buttonSize) 2328 .onClick(() => { 2329 if (index as number == 0) { 2330 this.sliderShow = false 2331 if (this.controller) { 2332 let selection = this.controller.getSelection(); 2333 let spans = selection.spans 2334 spans.forEach((item: RichEditorTextSpanResult | RichEditorImageSpanResult, index) => { 2335 if (typeof (item as RichEditorTextSpanResult)['textStyle'] != 'undefined') { 2336 let span = item as RichEditorTextSpanResult 2337 this.textStyle = span.textStyle 2338 let start = span.offsetInSpan[0] 2339 let end = span.offsetInSpan[1] 2340 let offset = span.spanPosition.spanRange[0] 2341 if (this.textStyle.fontWeight != 11) { 2342 this.textStyle.fontWeight = FontWeight.Bolder 2343 } else { 2344 this.textStyle.fontWeight = FontWeight.Normal 2345 } 2346 this.controller.updateSpanStyle({ 2347 start: offset + start, 2348 end: offset + end, 2349 textStyle: this.textStyle 2350 }) 2351 } 2352 }) 2353 } 2354 } else if (index as number == 1) { 2355 this.sliderShow = false 2356 if (this.controller) { 2357 let selection = this.controller.getSelection(); 2358 let spans = selection.spans 2359 spans.forEach((item: RichEditorTextSpanResult | RichEditorImageSpanResult, index) => { 2360 if (typeof (item as RichEditorTextSpanResult)['textStyle'] != 'undefined') { 2361 let span = item as RichEditorTextSpanResult 2362 this.textStyle = span.textStyle 2363 let start = span.offsetInSpan[0] 2364 let end = span.offsetInSpan[1] 2365 let offset = span.spanPosition.spanRange[0] 2366 if (this.textStyle.fontStyle == FontStyle.Italic) { 2367 this.textStyle.fontStyle = FontStyle.Normal 2368 } else { 2369 this.textStyle.fontStyle = FontStyle.Italic 2370 } 2371 this.controller.updateSpanStyle({ 2372 start: offset + start, 2373 end: offset + end, 2374 textStyle: this.textStyle 2375 }) 2376 } 2377 }) 2378 } 2379 } else if (index as number == 2) { 2380 this.sliderShow = false 2381 if (this.controller) { 2382 let selection = this.controller.getSelection(); 2383 let spans = selection.spans 2384 spans.forEach((item: RichEditorTextSpanResult | RichEditorImageSpanResult, index) => { 2385 if (typeof (item as RichEditorTextSpanResult)['textStyle'] != 'undefined') { 2386 let span = item as RichEditorTextSpanResult 2387 this.textStyle = span.textStyle 2388 let start = span.offsetInSpan[0] 2389 let end = span.offsetInSpan[1] 2390 let offset = span.spanPosition.spanRange[0] 2391 if (this.textStyle.decoration) { 2392 if (this.textStyle.decoration.type == TextDecorationType.Underline) { 2393 this.textStyle.decoration.type = TextDecorationType.None 2394 } else { 2395 this.textStyle.decoration.type = TextDecorationType.Underline 2396 } 2397 } else { 2398 this.textStyle.decoration = { type: TextDecorationType.Underline, color: Color.Black, style: TextDecorationStyle.SOLID } 2399 } 2400 this.controller.updateSpanStyle({ 2401 start: offset + start, 2402 end: offset + end, 2403 textStyle: this.textStyle 2404 }) 2405 } 2406 }) 2407 } 2408 } else if (index as number == 3) { 2409 this.sliderShow = !this.sliderShow 2410 } else if (index as number == 4) { 2411 this.sliderShow = false 2412 if (this.controller) { 2413 let selection = this.controller.getSelection(); 2414 let spans = selection.spans 2415 spans.forEach((item: RichEditorTextSpanResult | RichEditorImageSpanResult, index) => { 2416 if (typeof (item as RichEditorTextSpanResult)['textStyle'] != 'undefined') { 2417 let span = item as RichEditorTextSpanResult 2418 this.textStyle = span.textStyle 2419 let start = span.offsetInSpan[0] 2420 let end = span.offsetInSpan[1] 2421 let offset = span.spanPosition.spanRange[0] 2422 if (this.textStyle.fontColor == Color.Orange || this.textStyle.fontColor == '#FFFFA500') { 2423 this.textStyle.fontColor = Color.Black 2424 } else { 2425 this.textStyle.fontColor = Color.Orange 2426 } 2427 this.controller.updateSpanStyle({ 2428 start: offset + start, 2429 end: offset + end, 2430 textStyle: this.textStyle 2431 }) 2432 } 2433 }) 2434 } 2435 } 2436 }) 2437 .onTouch((event?: TouchEvent | undefined) => { 2438 if(event != undefined){ 2439 if (event.type === TouchType.Down) { 2440 this.iconBgColor[index as number] = $r('sys.color.ohos_id_color_click_effect') 2441 } 2442 if (event.type === TouchType.Up) { 2443 this.iconBgColor[index as number] = this.colorTransparent 2444 } 2445 } 2446 }) 2447 .onHover((isHover?: boolean, event?: HoverEvent) => { 2448 this.iconBgColor.forEach((icon:ResourceColor, index1) => { 2449 this.iconBgColor[index1] = this.colorTransparent 2450 }) 2451 if(isHover != undefined) { 2452 this.iconBgColor[index as number] = $r('sys.color.ohos_id_color_hover') 2453 } 2454 }) 2455 .backgroundColor(this.iconBgColor[index as number]) 2456 }) 2457 } 2458 } 2459 .clip(true) 2460 .width(this.theme.defaultMenuWidth) 2461 .padding(this.theme.expandedOptionPadding) 2462 .borderRadius(this.theme.containerBorderRadius) 2463 .margin({ bottom: this.theme.menuSpacing }) 2464 .backgroundColor(this.theme.backGroundColor) 2465 .shadow(this.theme.iconPanelShadowStyle) 2466 } 2467 2468 @Builder 2469 SystemMenu() { 2470 Column() { 2471 Menu() { 2472 if (this.controller) { 2473 MenuItemGroup() { 2474 MenuItem({ startIcon: this.theme.cutIcon, content: "剪切", labelInfo: "Ctrl+X" }) 2475 .onClick(() => { 2476 if (!this.controller) { 2477 return 2478 } 2479 let richEditorSelection = this.controller.getSelection() 2480 this.PushDataToPasteboard(richEditorSelection); 2481 this.controller.deleteSpans({ 2482 start: richEditorSelection.selection[0], 2483 end: richEditorSelection.selection[1] 2484 }) 2485 }) 2486 MenuItem({ startIcon: this.theme.copyIcon, content: "复制", labelInfo: "Ctrl+C" }) 2487 .onClick(() => { 2488 if (!this.controller) { 2489 return 2490 } 2491 let richEditorSelection = this.controller.getSelection() 2492 this.PushDataToPasteboard(richEditorSelection); 2493 this.controller.closeSelectionMenu() 2494 }) 2495 MenuItem({ startIcon: this.theme.pasteIcon, content: "粘贴", labelInfo: "Ctrl+V" }) 2496 .enabled(this.pasteEnable) 2497 .onClick(() => { 2498 if (!this.controller) { 2499 return 2500 } 2501 let richEditorSelection = this.controller.getSelection() 2502 this.PopDataFromPasteboard(richEditorSelection) 2503 }) 2504 MenuItem({ startIcon: this.theme.selectAllIcon, content: "全选", labelInfo: "Ctrl+A" }) 2505 .visibility(this.visibilityValue) 2506 .onClick(() => { 2507 if (!this.controller) { 2508 return 2509 } 2510 this.controller.setSelection(-1, -1) 2511 this.visibilityValue = Visibility.None 2512 }) 2513 MenuItem({ startIcon: this.theme.shareIcon, content: "分享", labelInfo: "" }) 2514 .enabled(false) 2515 MenuItem({ startIcon: this.theme.translateIcon, content: "翻译", labelInfo: "" }) 2516 .enabled(false) 2517 MenuItem({ startIcon: this.theme.searchIcon, content: "搜索", labelInfo: "" }) 2518 .enabled(false) 2519 } 2520 } 2521 } 2522 .onVisibleAreaChange([0.0, 1.0], () => { 2523 if (!this.controller) { 2524 return 2525 } 2526 let richEditorSelection = this.controller.getSelection() 2527 let start = richEditorSelection.selection[0] 2528 let end = richEditorSelection.selection[1] 2529 if (start === 0 && this.controller.getSpans({ start: end + 1, end: end + 1 }).length === 0) { 2530 this.visibilityValue = Visibility.None 2531 } else { 2532 this.visibilityValue = Visibility.Visible 2533 } 2534 }) 2535 .radius(this.theme.containerBorderRadius) 2536 .clip(true) 2537 .backgroundColor(Color.White) 2538 .width(this.theme.defaultMenuWidth) 2539 } 2540 .width(this.theme.defaultMenuWidth) 2541 } 2542 2543 @Builder sliderPanel() { 2544 Column() { 2545 Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) { 2546 Text('A').fontSize(15) 2547 Slider({ value: this.textSize, step: 10, style: SliderStyle.InSet }) 2548 .width(210) 2549 .onChange((value: number, mode: SliderChangeMode) => { 2550 if (this.controller) { 2551 let selection = this.controller.getSelection(); 2552 if (mode == SliderChangeMode.End) { 2553 if (this.textSize == undefined) { 2554 this.textSize = 0 2555 } 2556 let spans = selection.spans 2557 spans.forEach((item: RichEditorTextSpanResult | RichEditorImageSpanResult, index) => { 2558 if (typeof (item as RichEditorTextSpanResult)['textStyle'] != 'undefined') { 2559 this.textSize = Math.max(this.textSize, (item as RichEditorTextSpanResult).textStyle.fontSize) 2560 } 2561 }) 2562 } 2563 if (mode == SliderChangeMode.Moving || mode == SliderChangeMode.Click) { 2564 this.start = selection.selection[0] 2565 this.end = selection.selection[1] 2566 this.textSize = value 2567 this.controller.updateSpanStyle({ 2568 start: this.start, 2569 end: this.end, 2570 textStyle: { fontSize: this.textSize } 2571 }) 2572 } 2573 } 2574 }) 2575 Text('A').fontSize(20).fontWeight(FontWeight.Medium) 2576 }.borderRadius(this.theme.containerBorderRadius) 2577 } 2578 .shadow(ShadowStyle.OUTER_DEFAULT_MD) 2579 .backgroundColor(Color.White) 2580 .borderRadius(this.theme.containerBorderRadius) 2581 .padding(15) 2582 .height(48) 2583 } 2584} 2585``` 2586> **说明:** 2587> 2588> 系统暂未预置加粗、斜体等图标,示例代码使用系统默认图标,开发者使用时需自行替换iconArr中的资源。 2589 2590 2591 2592### 示例4(更新图片样式) 2593通过[updateSpanStyle](#updatespanstyle)接口更新已有图片样式。 2594 2595```ts 2596// xxx.ets 2597@Entry 2598@Component 2599struct Index { 2600 controller: RichEditorController = new RichEditorController(); 2601 options: RichEditorOptions = { controller: this.controller }; 2602 private start: number = -1; 2603 private end: number = -1; 2604 @State message: string = "[-1, -1]" 2605 @State content: string = "" 2606 @State paddingVal: number = 5 2607 @State borderRad: number = 4 2608 2609 build() { 2610 Column() { 2611 Column() { 2612 Text("selection range:").width("100%") 2613 Text() { 2614 Span(this.message) 2615 }.width("100%") 2616 Text("selection content:").width("100%") 2617 Text() { 2618 Span(this.content) 2619 }.width("100%") 2620 } 2621 .borderWidth(1) 2622 .borderColor(Color.Red) 2623 .width("100%") 2624 .height("20%") 2625 2626 Row() { 2627 Button("updateSpanStyle1") 2628 .fontSize(12) 2629 .onClick(() => { 2630 this.controller.updateSpanStyle({ 2631 start: this.start, 2632 textStyle: 2633 { 2634 fontWeight: FontWeight.Bolder 2635 }, 2636 imageStyle: { 2637 size: ["80px", "80px"], 2638 layoutStyle: { 2639 borderRadius: undefined, 2640 margin: undefined 2641 } 2642 } 2643 }) 2644 }) 2645 2646 Button("updateSpanStyle2") 2647 .fontSize(12) 2648 .onClick(() => { 2649 this.controller.updateSpanStyle({ 2650 start: this.start, 2651 textStyle: 2652 { 2653 fontWeight: FontWeight.Bolder 2654 }, 2655 imageStyle: { 2656 size: ["70px", "70px"], 2657 layoutStyle: { 2658 borderRadius: { topLeft: '100px', topRight: '20px', bottomLeft: '100px', bottomRight: '20px' }, 2659 margin: { left: '30px', top: '20px', right: '20px', bottom: '20px' } 2660 } 2661 } 2662 }) 2663 }) 2664 2665 Button("updateSpanStyle3") 2666 .fontSize(12) 2667 .onClick(() => { 2668 this.controller.updateSpanStyle({ 2669 start: this.start, 2670 textStyle: 2671 { 2672 fontWeight: FontWeight.Bolder 2673 }, 2674 imageStyle: { 2675 size: ["60px", "60px"], 2676 layoutStyle: { 2677 borderRadius: '-10px', 2678 margin: '-10px' 2679 } 2680 } 2681 }) 2682 }) 2683 } 2684 .borderWidth(1) 2685 .borderColor(Color.Red) 2686 .width("100%") 2687 .height("10%") 2688 2689 Row() { 2690 Button('addImageSpan1') 2691 .fontSize(12) 2692 .onClick(() => { 2693 this.controller.addImageSpan($r('app.media.app_icon'), { 2694 imageStyle: { 2695 size: ["80px", "80px"], 2696 layoutStyle: { 2697 borderRadius: '50px', 2698 margin: '40px' 2699 } 2700 } 2701 }) 2702 }) 2703 2704 Button('addImageSpan2') 2705 .fontSize(12) 2706 .onClick(() => { 2707 this.controller.addImageSpan($r('app.media.app_icon'), { 2708 imageStyle: { 2709 size: ["100px", "100px"], 2710 verticalAlign: ImageSpanAlignment.BOTTOM, 2711 layoutStyle: { 2712 borderRadius: undefined, 2713 margin: undefined 2714 } 2715 } 2716 }) 2717 }) 2718 2719 Button('addImageSpan3') 2720 .fontSize(12) 2721 .onClick(() => { 2722 this.controller.addImageSpan($r('app.media.app_icon'), { 2723 imageStyle: { 2724 size: ["60px", "60px"], 2725 verticalAlign: ImageSpanAlignment.BOTTOM, 2726 layoutStyle: { 2727 borderRadius: { topLeft: '10px', topRight: '20px', bottomLeft: '30px', bottomRight: '40px' }, 2728 margin: { left: '10px', top: '20px', right: '30px', bottom: '40px' } 2729 } 2730 } 2731 }) 2732 }) 2733 } 2734 .borderWidth(1) 2735 .borderColor(Color.Red) 2736 .width("100%") 2737 .height("10%") 2738 2739 Column() { 2740 RichEditor(this.options) 2741 .onReady(() => { 2742 this.controller.addTextSpan("0123456789", 2743 { 2744 style: 2745 { 2746 fontColor: Color.Orange, 2747 fontSize: 30 2748 } 2749 }) 2750 2751 this.controller.addImageSpan($r("app.media.app_icon"), 2752 { 2753 imageStyle: 2754 { 2755 size: ["60px", "60px"], 2756 verticalAlign: ImageSpanAlignment.BOTTOM, 2757 layoutStyle: { 2758 borderRadius: { topLeft: '10px', topRight: '20px', bottomLeft: '30px', bottomRight: '40px' }, 2759 margin: { left: '10px', top: '20px', right: '30px', bottom: '40px' } 2760 } 2761 } 2762 }) 2763 2764 this.controller.addTextSpan("0123456789", 2765 { 2766 style: 2767 { 2768 fontColor: Color.Black, 2769 fontSize: 30 2770 } 2771 }) 2772 }) 2773 .onSelect((value: RichEditorSelection) => { 2774 this.start = value.selection[0]; 2775 this.end = value.selection[1]; 2776 this.message = "[" + this.start + ", " + this.end + "]" 2777 }) 2778 .aboutToIMEInput((value: RichEditorInsertValue) => { 2779 console.log("---------------------- aboutToIMEInput ----------------------") 2780 console.log("insertOffset:" + value.insertOffset) 2781 console.log("insertValue:" + value.insertValue) 2782 return true; 2783 }) 2784 .onIMEInputComplete((value: RichEditorTextSpanResult) => { 2785 console.log("---------------------- onIMEInputComplete ---------------------") 2786 console.log("spanIndex:" + value.spanPosition.spanIndex) 2787 console.log("spanRange:[" + value.spanPosition.spanRange[0] + "," + value.spanPosition.spanRange[1] + "]") 2788 console.log("offsetInSpan:[" + value.offsetInSpan[0] + "," + value.offsetInSpan[1] + "]") 2789 console.log("value:" + value.value) 2790 }) 2791 .aboutToDelete((value: RichEditorDeleteValue) => { 2792 console.log("---------------------- aboutToDelete --------------------------") 2793 console.log("offset:" + value.offset) 2794 console.log("direction:" + value.direction) 2795 console.log("length:" + value.length) 2796 value.richEditorDeleteSpans.forEach(item => { 2797 console.log("---------------------- item --------------------------") 2798 console.log("spanIndex:" + item.spanPosition.spanIndex) 2799 console.log("spanRange:[" + item.spanPosition.spanRange[0] + "," + item.spanPosition.spanRange[1] + "]") 2800 console.log("offsetInSpan:[" + item.offsetInSpan[0] + "," + item.offsetInSpan[1] + "]") 2801 if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { 2802 console.log("image:" + (item as RichEditorImageSpanResult).valueResourceStr) 2803 } else { 2804 console.log("text:" + (item as RichEditorTextSpanResult).value) 2805 } 2806 }) 2807 return true; 2808 }) 2809 .onDeleteComplete(() => { 2810 console.log("---------------------- onDeleteComplete ------------------------") 2811 }) 2812 .borderWidth(1) 2813 .borderColor(Color.Green) 2814 .width("100%") 2815 .height('80.00%') 2816 } 2817 .borderWidth(1) 2818 .borderColor(Color.Red) 2819 .width("100%") 2820 .height("70%") 2821 } 2822 } 2823} 2824``` 2825 2826 2827### 示例5(Span绑定手势事件) 2828为Span绑定[gesture](#richeditorgesture11)回调。 2829 2830```ts 2831// xxx.ets 2832@Entry 2833@Component 2834struct Index { 2835 controller: RichEditorController = new RichEditorController() 2836 options: RichEditorOptions = { controller: this.controller }; 2837 @State textFlag: string = "TextFlag"; 2838 2839 build() { 2840 Column() { 2841 Column() { 2842 Text(this.textFlag) 2843 .copyOption(CopyOptions.InApp) 2844 .fontSize(50) 2845 .height(150) 2846 } 2847 Divider() 2848 Column() { 2849 RichEditor(this.options) 2850 .onReady(() => { 2851 this.controller.addTextSpan('Area1\n', { 2852 style: 2853 { 2854 fontColor: Color.Orange, 2855 fontSize: 50 2856 }, 2857 gesture: 2858 { 2859 onClick: () => { 2860 this.textFlag = "Area1 is onClick." 2861 }, 2862 onLongPress: () => { 2863 this.textFlag = "Area1 is onLongPress." 2864 } 2865 } 2866 }) 2867 2868 this.controller.addTextSpan('Area2\n', { 2869 style: 2870 { 2871 fontColor: Color.Blue, 2872 fontSize: 50 2873 }, 2874 gesture: 2875 { 2876 onClick: () => { 2877 this.textFlag = "Area2 is onClick." 2878 }, 2879 onLongPress: () => { 2880 this.textFlag = "Area2 is onLongPress." 2881 } 2882 } 2883 }) 2884 2885 this.controller.addImageSpan($r("app.media.icon"), 2886 { 2887 imageStyle: 2888 { 2889 size: ["100px", "100px"], 2890 layoutStyle: { 2891 margin: 5, 2892 borderRadius: 15 2893 } 2894 }, 2895 gesture: 2896 { 2897 onClick: () => { 2898 this.textFlag = "ImageSpan is onClick." 2899 }, 2900 onLongPress: () => { 2901 this.textFlag = "ImageSpan is onLongPress." 2902 } 2903 }, 2904 onHover : (status) => { 2905 this.textFlag = "ImageSpan is onHover :" + status 2906 } 2907 }) 2908 }) 2909 } 2910 .borderWidth(1) 2911 .borderColor(Color.Red) 2912 .width("100%") 2913 .height("70%") 2914 } 2915 } 2916} 2917``` 2918 2919 2920### 示例6(更新和获取段落样式) 2921通过[updateParagraphStyle](#updateparagraphstyle11)接口更新段落样式,通过[getParagraphs](#getparagraphs11)接口获取指定范围段落的信息。 2922 2923```ts 2924// xxx.ets 2925@Entry 2926@Component 2927struct Index { 2928 controller: RichEditorController = new RichEditorController(); 2929 private spanParagraphs: RichEditorParagraphResult[] = []; 2930 2931 build() { 2932 Column() { 2933 RichEditor({ controller: this.controller }) 2934 .onReady(() => { 2935 this.controller.addTextSpan("0123456789\n", { 2936 style: { 2937 fontColor: Color.Pink, 2938 fontSize: "32", 2939 }, 2940 paragraphStyle: { 2941 textAlign: TextAlign.Start, 2942 leadingMargin: 16 2943 } 2944 }) 2945 this.controller.addTextSpan("0123456789") 2946 }) 2947 .width("80%") 2948 .height("30%") 2949 .border({ width: 1, radius: 5 }) 2950 .draggable(false) 2951 2952 Column({ space: 5 }) { 2953 Button("段落左对齐").onClick(() => { 2954 this.controller.updateParagraphStyle({ start: -1, end: -1, 2955 style: { 2956 textAlign: TextAlign.Start, 2957 } 2958 }) 2959 }) 2960 2961 Button("段落右对齐").onClick(() => { 2962 this.controller.updateParagraphStyle({ start: -1, end: -1, 2963 style: { 2964 textAlign: TextAlign.End, 2965 } 2966 }) 2967 }) 2968 2969 Button("段落居中").onClick(() => { 2970 this.controller.updateParagraphStyle({ start: -1, end: -1, 2971 style: { 2972 textAlign: TextAlign.Center, 2973 } 2974 }) 2975 }) 2976 Divider() 2977 Button("getParagraphs").onClick(() => { 2978 this.spanParagraphs = this.controller.getParagraphs({ start: -1, end: -1 }) 2979 console.log("RichEditor getParagraphs:" + JSON.stringify(this.spanParagraphs)) 2980 }) 2981 2982 Button("UpdateSpanStyle1").onClick(() => { 2983 this.controller.updateSpanStyle({ start: -1, end: -1, 2984 textStyle: { 2985 fontColor: Color.Brown, 2986 fontSize: 20 2987 } 2988 }) 2989 }) 2990 2991 Button("UpdateSpanStyle2").onClick(() => { 2992 this.controller.updateSpanStyle({ start: -1, end: -1, 2993 textStyle: { 2994 fontColor: Color.Green, 2995 fontSize: 30 2996 } 2997 }) 2998 }) 2999 } 3000 } 3001 } 3002} 3003``` 3004 3005 3006### 示例7(更新预设样式与缩进) 3007通过[setTypingStyle](#settypingstyle11)接口更新文本预设样式,通过[updateParagraphStyle](#updateparagraphstyle11)接口设置不同段落缩进。 3008 3009```ts 3010// xxx.ets 3011import { font } from '@kit.ArkUI' 3012 3013const canvasWidth = 1000 3014const canvasHeight = 100 3015const Indentation = 40 3016class LeadingMarginCreator { 3017 private settings: RenderingContextSettings = new RenderingContextSettings(true) 3018 private offscreenCanvas: OffscreenCanvas = new OffscreenCanvas(canvasWidth, canvasHeight) 3019 private offContext: OffscreenCanvasRenderingContext2D = this.offscreenCanvas.getContext("2d", this.settings) 3020 public static instance: LeadingMarginCreator = new LeadingMarginCreator() 3021 3022 // 获得字体字号级别,分别是从0到4级 3023 public getFontSizeLevel(fontSize: number) { 3024 const fontScaled: number = Number(fontSize) / 16 3025 3026 enum FontSizeScaleThreshold { 3027 SMALL = 0.9, 3028 NORMAL = 1.1, 3029 LEVEL_1_LARGE = 1.2, 3030 LEVEL_2_LARGE = 1.4, 3031 LEVEL_3_LARGE = 1.5 3032 } 3033 3034 let fontSizeLevel: number = 1 3035 3036 if (fontScaled < FontSizeScaleThreshold.SMALL) { 3037 fontSizeLevel = 0 3038 } else if (fontScaled < FontSizeScaleThreshold.NORMAL) { 3039 fontSizeLevel = 1 3040 } else if (fontScaled < FontSizeScaleThreshold.LEVEL_1_LARGE) { 3041 fontSizeLevel = 2 3042 } else if (fontScaled < FontSizeScaleThreshold.LEVEL_2_LARGE) { 3043 fontSizeLevel = 3 3044 } else if (fontScaled < FontSizeScaleThreshold.LEVEL_3_LARGE) { 3045 fontSizeLevel = 4 3046 } else { 3047 fontSizeLevel = 1 3048 } 3049 3050 return fontSizeLevel 3051 } 3052 // 获得字体字号级别,分别是从0到4级 3053 public getmarginLevel(Width: number) { 3054 let marginlevel: number = 1 3055 if (Width == 40) { 3056 marginlevel = 2.0 3057 } else if (Width == 80) { 3058 marginlevel = 1.0 3059 } else if (Width == 120) { 3060 marginlevel = 2/3 3061 } else if (Width == 160) { 3062 marginlevel = 0.5 3063 } else if (Width == 200) { 3064 marginlevel = 0.4 3065 } 3066 return marginlevel 3067 } 3068 3069 public genStrMark(fontSize: number, str: string): PixelMap { 3070 this.offContext = this.offscreenCanvas.getContext("2d", this.settings) 3071 this.clearCanvas() 3072 this.offContext.font = fontSize + 'vp sans-serif' 3073 this.offContext.fillText(str + '.', 0, fontSize * 0.9) 3074 return this.offContext.getPixelMap(0, 0, fontSize * (str.length + 1) / 1.75, fontSize) 3075 } 3076 3077 public genSquareMark(fontSize: number): PixelMap { 3078 this.offContext = this.offscreenCanvas.getContext("2d", this.settings) 3079 this.clearCanvas() 3080 const coordinate = fontSize * (1 - 1 / 1.5) / 2 3081 const sideLength = fontSize / 1.5 3082 this.offContext.fillRect(coordinate, coordinate, sideLength, sideLength) 3083 return this.offContext.getPixelMap(0, 0, fontSize, fontSize) 3084 } 3085 3086 // 生成圆圈符号 3087 public genCircleMark(fontSize: number, width: number, level?: number ): PixelMap { 3088 const indentLevel = level ?? 1 3089 const offsetLevel = [22, 28, 32, 34, 38] 3090 const fontSizeLevel = this.getFontSizeLevel(fontSize) 3091 const marginlevel = this.getmarginLevel(width) 3092 const newCanvas = new OffscreenCanvas(canvasWidth, canvasHeight) 3093 const newOffContext: OffscreenCanvasRenderingContext2D = newCanvas.getContext("2d", this.settings) 3094 const centerCoordinate = 50 3095 const radius = 10 3096 this.clearCanvas() 3097 newOffContext.ellipse(100 * (indentLevel + 1) - centerCoordinate * marginlevel, offsetLevel[fontSizeLevel], radius * marginlevel, radius, 0, 0, 2 * Math.PI) 3098 newOffContext.fillStyle = '66FF0000' 3099 newOffContext.fill() 3100 return newOffContext.getPixelMap(0, 0, 100 + 100 * indentLevel, 100) 3101 } 3102 3103 private clearCanvas() { 3104 this.offContext.clearRect(0, 0, canvasWidth, canvasHeight) 3105 } 3106} 3107 3108@Entry 3109@Component 3110struct Index { 3111 controller: RichEditorController = new RichEditorController() 3112 options: RichEditorOptions = { controller: this.controller } 3113 private leadingMarkCreatorInstance = LeadingMarginCreator.instance 3114 private fontNameRawFile: string = 'MiSans-Bold' 3115 @State fs: number = 30 3116 @State cl: number = Color.Black 3117 private leftMargin: Dimension = 0 3118 private richEditorTextStyle: RichEditorTextStyle = {} 3119 3120 aboutToAppear() { 3121 font.registerFont({ 3122 familyName: 'MiSans-Bold', 3123 familySrc: '/font/MiSans-Bold.ttf' 3124 }) 3125 } 3126 3127 build() { 3128 Scroll() { 3129 Column() { 3130 RichEditor(this.options) 3131 .onReady(() => { 3132 this.controller.addTextSpan("0123456789\n", 3133 { 3134 style: 3135 { 3136 fontWeight: 'medium', 3137 fontFamily: this.fontNameRawFile, 3138 fontColor: Color.Red, 3139 fontSize: 50, 3140 fontStyle: FontStyle.Italic, 3141 decoration: { type: TextDecorationType.Underline, color: Color.Green } 3142 } 3143 }) 3144 3145 this.controller.addTextSpan("abcdefg", 3146 { 3147 style: 3148 { 3149 fontWeight: FontWeight.Lighter, 3150 fontFamily: 'HarmonyOS Sans', 3151 fontColor: 'rgba(0,128,0,0.5)', 3152 fontSize: 30, 3153 fontStyle: FontStyle.Normal, 3154 decoration: { type: TextDecorationType.Overline, color: 'rgba(169, 26, 246, 0.50)' } 3155 } 3156 }) 3157 }) 3158 .borderWidth(1) 3159 .borderColor(Color.Green) 3160 .width("100%") 3161 .height("50%") 3162 3163 Row({ space: 5 }) { 3164 Button('setTypingStyle1') 3165 .fontSize(10) 3166 .onClick(() => { 3167 this.controller.setTypingStyle( 3168 { 3169 fontWeight: 'medium', 3170 fontFamily: this.fontNameRawFile, 3171 fontColor: Color.Blue, 3172 fontSize: 50, 3173 fontStyle: FontStyle.Italic, 3174 decoration: { type: TextDecorationType.Underline, color: Color.Green } 3175 }) 3176 }) 3177 3178 Button('setTypingStyle2') 3179 .fontSize(10) 3180 .onClick(() => { 3181 this.controller.setTypingStyle( 3182 { 3183 fontWeight: FontWeight.Lighter, 3184 fontFamily: 'HarmonyOS Sans', 3185 fontColor: Color.Green, 3186 fontSize: '30', 3187 fontStyle: FontStyle.Normal, 3188 decoration: { type: TextDecorationType.Overline, color: 'rgba(169, 26, 246, 0.50)' } 3189 }) 3190 }) 3191 } 3192 Divider() 3193 Button("getTypingStyle").onClick(() => { 3194 this.richEditorTextStyle = this.controller.getTypingStyle() 3195 console.log("RichEditor getTypingStyle:" + JSON.stringify(this.richEditorTextStyle)) 3196 }) 3197 Divider() 3198 Row({ space: 5 }) { 3199 Button("向右列表缩进").onClick(() => { 3200 let margin = Number(this.leftMargin) 3201 if (margin < 200) { 3202 margin += Indentation 3203 this.leftMargin = margin 3204 } 3205 this.controller.updateParagraphStyle({ 3206 start: -10, 3207 end: -10, 3208 style: { 3209 leadingMargin : { 3210 pixelMap : this.leadingMarkCreatorInstance.genCircleMark(100, margin, 1), 3211 size: [margin, 40] 3212 } 3213 } 3214 }) 3215 }) 3216 3217 Button("向左列表缩进").onClick(() => { 3218 let margin = Number(this.leftMargin) 3219 if (margin > 0) { 3220 margin -= Indentation 3221 this.leftMargin = margin 3222 } 3223 this.controller.updateParagraphStyle({ 3224 start: -10, 3225 end: -10, 3226 style: { 3227 leadingMargin : { 3228 pixelMap : this.leadingMarkCreatorInstance.genCircleMark(100, margin, 1), 3229 size: [margin, 40] 3230 } 3231 } 3232 }) 3233 }) 3234 } 3235 Divider() 3236 Row({ space: 5 }) { 3237 Button("向右空白缩进").onClick(() => { 3238 let margin = Number(this.leftMargin) 3239 if (margin < 200) { 3240 margin += Indentation 3241 this.leftMargin = margin 3242 } 3243 this.controller.updateParagraphStyle({ 3244 start: -10, 3245 end: -10, 3246 style: { 3247 leadingMargin: margin 3248 } 3249 }) 3250 }) 3251 3252 Button("向左空白缩进").onClick(() => { 3253 let margin = Number(this.leftMargin) 3254 if (margin > 0) { 3255 margin -= Indentation 3256 this.leftMargin = margin 3257 } 3258 this.controller.updateParagraphStyle({ 3259 start: -10, 3260 end: -10, 3261 style: { 3262 leadingMargin: margin 3263 } 3264 }) 3265 }) 3266 } 3267 }.borderWidth(1).borderColor(Color.Red) 3268 } 3269 } 3270} 3271``` 3272 3273 3274### 示例8(设置文本字重与阴影) 3275通过[updateParagraphStyle](#updateparagraphstyle11)接口设置文本字重与阴影。 3276 3277``` ts 3278@Entry 3279@Component 3280struct Index { 3281 controller: RichEditorController = new RichEditorController(); 3282 options: RichEditorOptions = { controller: this.controller }; 3283 private start: number = -1; 3284 private end: number = -1; 3285 @State message: string = "[-1, -1]" 3286 @State content: string = "" 3287 @State visable :number = 0; 3288 @State index:number = 0; 3289 @State offsetx: number = 0; 3290 @State textShadows : (ShadowOptions | Array<ShadowOptions> ) = 3291 [{ radius: 10, color: Color.Red, offsetX: 10, offsetY: 0 },{ radius: 10, color: Color.Black, offsetX: 20, offsetY: 0 }, 3292 { radius: 10, color: Color.Brown, offsetX: 30, offsetY: 0 },{ radius: 10, color: Color.Green, offsetX: 40, offsetY: 0 }, 3293 { radius: 10, color: Color.Yellow, offsetX: 100, offsetY: 0 }] 3294 @State textshadowOf : ShadowOptions[] = [] 3295 build() { 3296 Column() { 3297 Column() { 3298 Text("selection range:").width("100%") 3299 Text() { 3300 Span(this.message) 3301 }.width("100%") 3302 Text("selection content:").width("100%") 3303 Text() { 3304 Span(this.content) 3305 }.width("100%") 3306 } 3307 .borderWidth(1) 3308 .borderColor(Color.Red) 3309 .width("100%") 3310 .height("20%") 3311 Row() { 3312 Button("更新样式: 加粗 & 文本阴影").onClick(() => { 3313 this.controller.updateSpanStyle({ 3314 start: this.start, 3315 end: this.end, 3316 textStyle: 3317 { 3318 fontWeight: FontWeight.Bolder, 3319 textShadow: this.textShadows 3320 } 3321 }) 3322 }) 3323 } 3324 .borderWidth(1) 3325 .borderColor(Color.Red) 3326 .width("100%") 3327 .height("10%") 3328 Column() { 3329 RichEditor(this.options) 3330 .onReady(() => { 3331 this.controller.addTextSpan("0123456789", 3332 { 3333 style: 3334 { 3335 fontColor: Color.Orange, 3336 fontSize: 30, 3337 textShadow: { radius: 10, color: Color.Blue, offsetX: 10, offsetY: 0 } 3338 } 3339 }) 3340 }) 3341 .borderWidth(1) 3342 .borderColor(Color.Green) 3343 .width("100%") 3344 .height("30%") 3345 } 3346 .borderWidth(1) 3347 .borderColor(Color.Red) 3348 .width("100%") 3349 .height("70%") 3350 } 3351 } 3352} 3353``` 3354 3355 3356 3357### 示例9(添加用户自定义布局Span) 3358通过[addBuilderSpan](#addbuilderspan11)接口添加用户自定义布局Span。 3359 3360``` ts 3361@Builder 3362function placeholderBuilder2() { 3363 Row({ space: 2 }) { 3364 Image($r("app.media.icon")).width(24).height(24).margin({ left: -5 }) 3365 Text('okokokok').fontSize(10) 3366 }.width('20%').height(50).padding(10).backgroundColor(Color.Red) 3367} 3368 3369// xxx.ets 3370@Entry 3371@Component 3372struct Index { 3373 controller: RichEditorController = new RichEditorController(); 3374 option: RichEditorOptions = { controller: this.controller }; 3375 private start: number = 2; 3376 private end: number = 4; 3377 @State message: string = "[-1, -1]" 3378 @State content: string = "" 3379 private my_offset: number | undefined = undefined 3380 private my_builder: CustomBuilder = undefined 3381 @BuilderParam my_builder2:() => void = placeholderBuilder2; 3382 3383 @Builder 3384 placeholderBuilder() { 3385 Row({ space: 2 }) { 3386 Image($r("app.media.icon")).width(24).height(24).margin({ left: -5 }) 3387 Text('Custom Popup').fontSize(10) 3388 }.width(100).height(50).padding(5) 3389 } 3390 3391 @Builder 3392 placeholderBuilder3() { 3393 Text("hello").padding('20').borderWidth(1).width('100%') 3394 } 3395 3396 @Builder 3397 placeholderBuilder4() { 3398 Column() { 3399 Column({ space: 5 }) { 3400 Text('direction:Row').fontSize(9).fontColor(0xCCCCCC).width('90%') 3401 Flex({ direction: FlexDirection.Row }) { // 子组件在容器主抽上行布局 3402 Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) 3403 Text('1').width('20%').height(50).backgroundColor(0xD2B48C) 3404 Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) 3405 Text('1').width('20%').height(50).backgroundColor(0xD2B48C) 3406 } 3407 .height(70) 3408 .width('90%') 3409 .padding(10) 3410 .backgroundColor(0xAFEEEE) 3411 3412 Text('direction:RowReverse').fontSize(9).fontColor(0xCCCCCC).width('90%') 3413 Flex({ direction: FlexDirection.RowReverse }) { // 子组件在容器主抽上反向行布局 3414 Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) 3415 Text('1').width('20%').height(50).backgroundColor(0xD2B48C) 3416 Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) 3417 Text('1').width('20%').height(50).backgroundColor(0xD2B48C) 3418 } 3419 .height(70) 3420 .width('90%') 3421 .padding(10) 3422 .backgroundColor(0xAFEEEE) 3423 3424 Text('direction:Column').fontSize(9).fontColor(0xCCCCCC).width('90%') 3425 Flex({ direction: FlexDirection.Column }) { // 子组件在容器主抽上列布局 3426 Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) 3427 Text('1').width('20%').height(40).backgroundColor(0xD2B48C) 3428 Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) 3429 Text('1').width('20%').height(40).backgroundColor(0xD2B48C) 3430 } 3431 .height(160) 3432 .width('90%') 3433 .padding(10) 3434 .backgroundColor(0xAFEEEE) 3435 3436 Text('direction:ColumnReverse').fontSize(9).fontColor(0xCCCCCC).width('90%') 3437 Flex({ direction: FlexDirection.ColumnReverse }) { // 子组件在容器主抽上反向列布局 3438 Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) 3439 Text('1').width('20%').height(40).backgroundColor(0xD2B48C) 3440 Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) 3441 Text('1').width('20%').height(40).backgroundColor(0xD2B48C) 3442 } 3443 .height(160) 3444 .width('90%') 3445 .padding(10) 3446 .backgroundColor(0xAFEEEE) 3447 }.width('100%').margin({ top: 5 }) 3448 }.width('100%') 3449 } 3450 3451 @Builder 3452 MyMenu() { 3453 Menu() { 3454 MenuItem({ startIcon: $r("app.media.icon"), content: "菜单选项1" }) 3455 MenuItem({ startIcon: $r("app.media.icon"), content: "菜单选项2" }) 3456 .enabled(false) 3457 } 3458 } 3459 3460 build() { 3461 Column() { 3462 Column() { 3463 Text("selection range:").width("100%") 3464 Text() { 3465 Span(this.message) 3466 }.width("100%") 3467 3468 Text("selection content:").width("100%") 3469 Text() { 3470 Span(this.content) 3471 }.width("100%") 3472 } 3473 .borderWidth(1) 3474 .borderColor(Color.Red) 3475 .width("100%") 3476 .height("20%") 3477 3478 Row() { 3479 Button("获取选择内容 getSpans").onClick(() => { 3480 console.info('getSpans='+JSON.stringify(this.controller.getSpans({ start:1, end:5 }))) 3481 console.info('getParagraphs='+JSON.stringify(this.controller.getParagraphs({ start:1, end:5 }))) 3482 this.content = "" 3483 this.controller.getSpans({ 3484 start: this.start, 3485 end: this.end 3486 }).forEach(item => { 3487 if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { 3488 if ((item as RichEditorImageSpanResult).valueResourceStr == "") { 3489 console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + 3490 (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) 3491 } else { 3492 console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + 3493 (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + 3494 (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) 3495 } 3496 } else { 3497 this.content += (item as RichEditorTextSpanResult).value; 3498 this.content += "\n" 3499 console.info("text span: " + (item as RichEditorTextSpanResult).value) 3500 } 3501 }) 3502 }) 3503 Button("获取选择内容 getSelection").onClick(() => { 3504 this.content = ""; 3505 let select = this.controller.getSelection() 3506 console.info("selection start " + select.selection[0] + " end " + select.selection[1]) 3507 select.spans.forEach(item => { 3508 if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { 3509 if ((item as RichEditorImageSpanResult).valueResourceStr == "") { 3510 console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + 3511 (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) 3512 } else { 3513 console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + 3514 (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + 3515 (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) 3516 } 3517 } else { 3518 this.content += (item as RichEditorTextSpanResult).value; 3519 this.content += "\n" 3520 console.info("text span: " + (item as RichEditorTextSpanResult).value) 3521 } 3522 }) 3523 }) 3524 Button("删除选择内容").onClick(() => { 3525 this.controller.deleteSpans({ 3526 start: this.start, 3527 end: this.end 3528 }) 3529 }) 3530 } 3531 .borderWidth(1) 3532 .borderColor(Color.Red) 3533 .width("100%") 3534 .height("10%") 3535 3536 Column() { 3537 RichEditor(this.option) 3538 .onReady(() => { 3539 this.controller.addTextSpan("0123456789", 3540 { 3541 style: 3542 { 3543 fontColor: Color.Orange, 3544 fontSize: 30 3545 } 3546 }) 3547 this.controller.addImageSpan($r("app.media.icon"), 3548 { 3549 imageStyle: 3550 { 3551 size: ["57px", "57px"] 3552 } 3553 }) 3554 }) 3555 .onSelect((value: RichEditorSelection) => { 3556 this.start = value.selection[0]; 3557 this.end = value.selection[1]; 3558 this.message = "[" + this.start + ", " + this.end + "]" 3559 console.info("onSelect="+JSON.stringify(value)) 3560 }) 3561 .aboutToIMEInput((value: RichEditorInsertValue) => { 3562 console.log("---------------------- aboutToIMEInput --------------------") 3563 console.info("aboutToIMEInput="+JSON.stringify(value)) 3564 console.log("insertOffset:" + value.insertOffset) 3565 console.log("insertValue:" + value.insertValue) 3566 return true; 3567 }) 3568 .onIMEInputComplete((value: RichEditorTextSpanResult) => { 3569 console.log("---------------------- onIMEInputComplete --------------------") 3570 console.info("onIMEInputComplete="+JSON.stringify(value)) 3571 console.log("spanIndex:" + value.spanPosition.spanIndex) 3572 console.log("spanRange:[" + value.spanPosition.spanRange[0] + "," + value.spanPosition.spanRange[1] + "]") 3573 console.log("offsetInSpan:[" + value.offsetInSpan[0] + "," + value.offsetInSpan[1] + "]") 3574 console.log("value:" + value.value) 3575 }) 3576 .aboutToDelete((value: RichEditorDeleteValue) => { 3577 value.richEditorDeleteSpans.forEach(item => { 3578 console.log("---------------------- item --------------------") 3579 console.info("spanIndex=" + item.spanPosition.spanIndex) 3580 console.log("spanRange:[" + item.spanPosition.spanRange[0] + "," + item.spanPosition.spanRange[1] + "]") 3581 console.log("offsetInSpan:[" + item.offsetInSpan[0] + "," + item.offsetInSpan[1] + "]") 3582 if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { 3583 if ((item as RichEditorImageSpanResult).valueResourceStr == "") { 3584 console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + 3585 (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) 3586 } else { 3587 console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + 3588 (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + 3589 (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) 3590 } 3591 } else { 3592 console.info("delete text: " + (item as RichEditorTextSpanResult).value) 3593 } 3594 }) 3595 return true; 3596 }) 3597 .borderWidth(1) 3598 .borderColor(Color.Green) 3599 .width("100%") 3600 .height("30%") 3601 3602 Button("add span") 3603 .onClick(() => { 3604 let num = this.controller.addBuilderSpan(this.my_builder, { offset: this.my_offset }) 3605 console.info('addBuilderSpan return ' + num) 3606 }) 3607 Button("add image") 3608 .onClick(() => { 3609 let num = this.controller.addImageSpan($r("app.media.icon"), { 3610 imageStyle: { 3611 size: ["50px", "50px"], 3612 verticalAlign: ImageSpanAlignment.BOTTOM, 3613 layoutStyle: { 3614 borderRadius: undefined, 3615 margin: undefined 3616 } 3617 } 3618 }) 3619 console.info('addImageSpan return' + num) 3620 }) 3621 Row() { 3622 Button('builder1').onClick(() => { 3623 this.my_builder = () => { 3624 this.placeholderBuilder() 3625 } 3626 }) 3627 Button('builder2').onClick(() => { 3628 this.my_builder = () => { 3629 this.my_builder2() 3630 } 3631 }) 3632 Button('builder3').onClick(() => { 3633 this.my_builder = () => { 3634 this.placeholderBuilder3() 3635 } 3636 }) 3637 Button('builder4').onClick(() => { 3638 this.my_builder = () => { 3639 this.placeholderBuilder4() 3640 } 3641 }) 3642 } 3643 } 3644 .borderWidth(1) 3645 .borderColor(Color.Red) 3646 .width("100%") 3647 .height("70%") 3648 } 3649 } 3650} 3651``` 3652 3653 3654### 示例10(设置文本识别配置) 3655设置[enableDataDetector](#enabledatadetector11)为true时,通过[dataDetectorConfig](#datadetectorconfig11)接口设置文本识别配置。 3656 3657```ts 3658@Entry 3659@Component 3660struct TextExample7 { 3661 controller: RichEditorController = new RichEditorController(); 3662 options: RichEditorOptions = { controller: this.controller }; 3663 @State phoneNumber: string = '(86) (755) ********'; 3664 @State url: string = 'www.********.com'; 3665 @State email: string = '***@example.com'; 3666 @State address: string = 'XX省XX市XX区XXXX'; 3667 @State enableDataDetector: boolean = true; 3668 @State enablePreviewText: boolean = false; 3669 @State types: TextDataDetectorType[] = []; 3670 3671 build() { 3672 Row() { 3673 Column() { 3674 RichEditor(this.options) 3675 .onReady(() => { 3676 this.controller.addTextSpan('电话号码:' + this.phoneNumber + '\n', 3677 { 3678 style: 3679 { 3680 fontSize: 30 3681 } 3682 }) 3683 this.controller.addTextSpan('链接:' + this.url + '\n', 3684 { 3685 style: 3686 { 3687 fontSize: 30 3688 } 3689 }) 3690 this.controller.addTextSpan('邮箱:' + this.email + '\n', 3691 { 3692 style: 3693 { 3694 fontSize: 30 3695 } 3696 }) 3697 this.controller.addTextSpan('地址:' + this.address, 3698 { 3699 style: 3700 { 3701 fontSize: 30 3702 } 3703 }) 3704 }) 3705 .copyOptions(CopyOptions.InApp) 3706 .enableDataDetector(this.enableDataDetector) 3707 .dataDetectorConfig({types : this.types, onDetectResultUpdate: (result: string)=>{}}) 3708 .enablePreviewText(this.enablePreviewText) 3709 .borderWidth(1) 3710 .padding(10) 3711 .width('100%') 3712 } 3713 .width('100%') 3714 } 3715 } 3716} 3717``` 3718### 示例11(设置光标、手柄和底板颜色) 3719通过[caretColor](#caretcolor12)属性设置输入框光标、手柄颜色,通过[selectedBackgroundColor](#selectedbackgroundcolor12)属性设置文本选中底板颜色。 3720 3721``` ts 3722@Entry 3723@Component 3724struct RichEditorDemo { 3725 @State color: Color|string = "" 3726 controller: RichEditorController = new RichEditorController(); 3727 build() { 3728 Column() { 3729 Row(){ 3730 Button("改为红色").onClick(() => { 3731 this.color = Color.Red 3732 }) 3733 }.margin({top:50}) 3734 RichEditor({ controller: this.controller }) 3735 .onReady(()=>{ 3736 this.controller.addTextSpan('测试文字测试文字测试文字测试文字测试文字测试文字') 3737 }) 3738 .width("100%") 3739 .border({ width: 1, radius: 5 }) 3740 .key('RichEditor') 3741 .caretColor(this.color) //光标颜色 3742 .selectedBackgroundColor(this.color) //选中背景色 3743 .margin({top:50}) 3744 } 3745 .width('100%') 3746 } 3747} 3748``` 3749 3750 3751### 示例12(设置行高和字符间距) 3752通过[updateSpanStyle](#updatespanstyle)接口配置文本行高([lineHeight](#richeditortextstyle))和字符间距([letterSpacing](#richeditortextstyle))。 3753 3754```ts 3755@Entry 3756@Component 3757struct RichEditorDemo03 { 3758 controller: RichEditorController = new RichEditorController(); 3759 options: RichEditorOptions = { controller: this.controller }; 3760 @State start: number = -1; 3761 @State end: number = -1; 3762 @State LH:number = 50 3763 @State LS:number = 20 3764 3765 build() { 3766 Column() { 3767 Scroll(){ 3768 Column(){ 3769 Row() { 3770 Button("行高++").onClick(()=>{ 3771 this.LH = this.LH + 5 3772 this.controller.updateSpanStyle({ 3773 start: this.start, 3774 end: this.end, 3775 textStyle: 3776 { 3777 lineHeight: this.LH 3778 } 3779 }) 3780 }) 3781 Button("行高--").onClick(()=>{ 3782 this.LH = this.LH - 5 3783 this.controller.updateSpanStyle({ 3784 start: this.start, 3785 end: this.end, 3786 textStyle: 3787 { 3788 lineHeight: this.LH 3789 } 3790 }) 3791 }) 3792 Button("字符间距++").onClick(()=>{ 3793 this.LS = this.LS + 5 3794 this.controller.updateSpanStyle({ 3795 start: this.start, 3796 end: this.end, 3797 textStyle: 3798 { 3799 letterSpacing: this.LS 3800 } 3801 }) 3802 }) 3803 Button("字符间距--").onClick(()=>{ 3804 this.LS = this.LS - 5 3805 this.controller.updateSpanStyle({ 3806 start: this.start, 3807 end: this.end, 3808 textStyle: 3809 { 3810 letterSpacing: this.LS 3811 } 3812 }) 3813 }) 3814 } 3815 } 3816 }.borderWidth(1) 3817 .borderColor(Color.Red) 3818 .width("100%") 3819 .height("20%") 3820 .margin({top: 20}) 3821 3822 Scroll(){ 3823 Column() { 3824 Text("LineHeight:" + this.LH).width("100%") 3825 Text("LetterSpacing:" + this.LS).width("100%") 3826 } 3827 } 3828 .borderWidth(1) 3829 .borderColor(Color.Red) 3830 .width("100%") 3831 .height("20%") 3832 .margin({bottom: 20}) 3833 3834 Column() { 3835 RichEditor(this.options).clip(true).padding(10) 3836 .onReady(() => { 3837 this.controller.addTextSpan("012345", 3838 { 3839 style: 3840 { 3841 fontColor: Color.Orange, 3842 fontSize: 30, 3843 lineHeight: this.LH, 3844 letterSpacing: this.LS 3845 } 3846 }) 3847 this.controller.addTextSpan("6789", 3848 { 3849 style: 3850 { 3851 fontColor: Color.Black, 3852 fontSize: 30, 3853 lineHeight: this.LH, 3854 letterSpacing: this.LS 3855 } 3856 }) 3857 }) 3858 .borderWidth(1) 3859 .borderColor(Color.Green) 3860 .width(400) 3861 .height(400) 3862 } 3863 .borderWidth(1) 3864 .borderColor(Color.Red) 3865 .width("100%") 3866 .height("60%") 3867 } 3868 } 3869} 3870``` 3871 3872 3873### 示例13(自定义粘贴事件) 3874为组件添加[onPaste](#onpaste11)事件,通过[PasteEvent](#pasteevent11)自定义用户粘贴事件。 3875 3876```ts 3877@Entry 3878@Component 3879struct RichEditorDemo { 3880 controller: RichEditorController = new RichEditorController(); 3881 options: RichEditorOptions = { controller: this.controller }; 3882 3883 build() { 3884 Column({ space: 2 }) { 3885 RichEditor(this.options) 3886 .onReady(() => { 3887 this.controller.addTextSpan('RichEditor preventDefault') 3888 }) 3889 .onPaste((event?: PasteEvent) => { 3890 if (event != undefined && event.preventDefault) { 3891 event.preventDefault(); 3892 } 3893 }) 3894 .borderWidth(1) 3895 .borderColor(Color.Green) 3896 .width('100%') 3897 .height('40%') 3898 } 3899 } 3900} 3901``` 3902 3903 3904### 示例14(配置文字特性效果) 3905通过[addTextSpan](#addtextspan)接口设置文字特性效果([fontFeature](#richeditortextstyle))。当添加“ss01”特性的FontFeature属性时,数字“0”由原来的椭圆形改变为带有倒圆角形。 3906 3907```ts 3908@Entry 3909@Component 3910struct RichEditorExample { 3911 controller: RichEditorController = new RichEditorController(); 3912 options: RichEditorOptions = { controller: this.controller }; 3913 @State enableDataDetector: boolean = true; 3914 @State types: TextDataDetectorType[] = []; 3915 build() { 3916 Row() { 3917 Column() { 3918 RichEditor(this.options) 3919 .onReady(() => { 3920 this.controller.addTextSpan('This is ss01 off :' + '0000' + '\n', 3921 { 3922 style: 3923 { 3924 fontSize: 30 3925 } 3926 }) 3927 this.controller.addTextSpan('This is ss01 on :' + '0000' + '\n', 3928 { 3929 style: 3930 { 3931 fontSize: 30, 3932 fontFeature: "\"ss01\" 1" 3933 } 3934 }) 3935 }) 3936 .copyOptions(CopyOptions.InApp) 3937 .enableDataDetector(this.enableDataDetector) 3938 .dataDetectorConfig({types : this.types, onDetectResultUpdate: (result: string)=>{}}) 3939 .borderWidth(1) 3940 .padding(10) 3941 .width('100%') 3942 } 3943 .width('100%') 3944 .margin({top:150}) 3945 } 3946 } 3947} 3948``` 3949 3950 3951### 示例15(自定义键盘避让) 3952通过[customKeyboard](#customkeyboard)属性绑定自定义键盘,通过参数[KeyboardOptions](#keyboardoptions12)设置自定义键盘是否支持避让功能。 3953 3954```ts 3955@Entry 3956@Component 3957struct RichEditorExample { 3958 controller: RichEditorController = new RichEditorController() 3959 @State height1:string|number = '80%' 3960 @State height2:number = 100 3961 @State supportAvoidance:boolean = true; 3962 3963 // 自定义键盘组件 3964 @Builder CustomKeyboardBuilder() { 3965 Column() { 3966 Row(){ 3967 Button('增加特表情包').onClick(() => { 3968 this.controller.addTextSpan("\uD83D\uDE0A", 3969 { 3970 style: 3971 { 3972 fontColor: Color.Orange, 3973 } 3974 }) 3975 }) 3976 } 3977 Grid() { 3978 ForEach([1, 2, 3, 4, 5, 6, 7, 8, 9, '*', 0, '#'], (item: number | string) => { 3979 GridItem() { 3980 Button(item + "") 3981 .width(110).onClick(() => { 3982 this.controller.addTextSpan(item + '', { 3983 offset: this.controller.getCaretOffset(), 3984 style: 3985 { 3986 fontColor: Color.Orange, 3987 fontSize: 30 3988 } 3989 }) 3990 this.controller.setCaretOffset(this.controller.getCaretOffset() + item.toString().length) 3991 }) 3992 } 3993 }) 3994 }.maxCount(3).columnsGap(10).rowsGap(10).padding(5) 3995 }.backgroundColor(Color.Gray) 3996 } 3997 3998 build() { 3999 Column() { 4000 Row(){ 4001 Button("20%") 4002 .fontSize(24) 4003 .onClick(()=>{ 4004 this.height1 = "20%" 4005 }) 4006 Button("80%") 4007 .fontSize(24) 4008 .margin({left:20}) 4009 .onClick(()=>{ 4010 this.height1 = "80%" 4011 }) 4012 } 4013 .justifyContent(FlexAlign.Center) 4014 .alignItems(VerticalAlign.Bottom) 4015 .height(this.height1) 4016 .width("100%") 4017 .padding({bottom:50}) 4018 RichEditor({ controller: this.controller }) 4019 // 绑定自定义键盘 4020 .customKeyboard(this.CustomKeyboardBuilder(),{ supportAvoidance: this.supportAvoidance }).margin(10).border({ width: 1 }) 4021 .borderWidth(1) 4022 .borderColor(Color.Red) 4023 .width("100%") 4024 } 4025 } 4026} 4027``` 4028 4029 4030### 示例16(查看编辑状态) 4031通过[isEditing](#isediting12)接口获取当前富文本的编辑状态。为组件添加[onEditingChange](#oneditingchange12)事件,可通过打印日志,获取当前组件是否在编辑态。 4032 4033```ts 4034@Entry 4035@Component 4036struct RichEditor_onEditingChange { 4037 controller: RichEditorController = new RichEditorController() 4038 @State controllerIsEditing: boolean = false 4039 @Builder 4040 4041 build() { 4042 Column() { 4043 Row() { 4044 Button("点击查看编辑状态isEditing():").onClick(() => { 4045 this.controllerIsEditing = this.controller.isEditing() 4046 }) 4047 .padding(5) 4048 Text('' + this.controllerIsEditing) 4049 .width('100%') 4050 .padding(5) 4051 .fontColor(Color.Orange) 4052 .fontSize(20) 4053 } 4054 RichEditor({ controller: this.controller }) 4055 .onEditingChange((isEditing: boolean) => { 4056 console.log("Current Editing Status:" + isEditing) 4057 }) 4058 .height(400) 4059 .borderWidth(1) 4060 .borderColor(Color.Red) 4061 .width("100%") 4062 } 4063 } 4064} 4065``` 4066 4067 4068 4069### 示例17(配置文本变化回调) 4070为组件添加[onWillChange](#onwillchange12)事件,能够在组件执行增删操作前,触发回调。 4071 4072```ts 4073@Entry 4074@Component 4075struct RichEditorExample { 4076 controller: RichEditorController = new RichEditorController() 4077 build() { 4078 Column() { 4079 RichEditor({ controller: this.controller }) 4080 .height(200) 4081 .borderWidth(1) 4082 .borderColor(Color.Red) 4083 .width("100%") 4084 .onReady(() => { 4085 this.controller.addTextSpan('测试文字TestWord', { style: { fontColor: Color.Orange, fontSize: 30 } }) 4086 this.controller.updateSpanStyle({ 4087 start: -1, 4088 end: -1, 4089 textStyle: 4090 { 4091 fontWeight: FontWeight.Bolder 4092 } 4093 }) 4094 }) 4095 .onWillChange((value: RichEditorChangeValue) => { 4096 console.log('测试log: onWillChange') 4097 console.log('rangeBefore: ' + JSON.stringify(value.rangeBefore)) 4098 console.log('print replacedSpans') 4099 value.replacedSpans.forEach((item: RichEditorTextSpanResult) => { 4100 console.log('spanPosition:' + JSON.stringify(item.spanPosition)) 4101 console.log('value:' + item.value) 4102 console.log('textStyle:' + JSON.stringify(item.textStyle)) 4103 console.log('offsetInSpan:' + item.offsetInSpan) 4104 console.log('valueResource:' + item.valueResource) 4105 console.log('paragraphStyle:' + JSON.stringify(item.paragraphStyle)) 4106 }) 4107 console.log('print replacedImageSpans') 4108 value.replacedImageSpans.forEach((item: RichEditorImageSpanResult) => { 4109 console.log('spanPosition:' + JSON.stringify(item.spanPosition)) 4110 console.log('valuePixelMap:' + JSON.stringify(item.valuePixelMap)) 4111 console.log('valueResourceStr:' + item.valueResourceStr) 4112 console.log('imageStyle:' + JSON.stringify(item.imageStyle)) 4113 console.log('offsetInSpan:' + item.offsetInSpan) 4114 }) 4115 console.log('print replacedSymbolSpans') 4116 value.replacedSymbolSpans.forEach((item: RichEditorTextSpanResult) => { 4117 console.log('spanPosition:' + JSON.stringify(item.spanPosition)) 4118 console.log('value:' + item.value) 4119 console.log('offsetInSpan:' + item.offsetInSpan) 4120 console.log('symbolSpanStyle:' + JSON.stringify(item.symbolSpanStyle)) 4121 console.log('valueResource:' + item.valueResource) 4122 console.log('paragraphStyle:' + JSON.stringify(item.paragraphStyle)) 4123 }) 4124 return true 4125 }) 4126 .onDidChange((rangeBefore: TextRange, rangeAfter: TextRange) => { 4127 console.log('测试log: onDidChange') 4128 console.log('rangeBefore:' + JSON.stringify(rangeBefore)) 4129 console.log('rangeAfter:' + JSON.stringify(rangeAfter)) 4130 }) 4131 .onCut((event:CutEvent) => { 4132 event.preventDefault!() 4133 console.log('测试log:onCut') 4134 }) 4135 .onCopy((event:CopyEvent) => { 4136 event.preventDefault!() 4137 console.log('测试log:onCopy') 4138 }) 4139 .onPaste(()=>{ 4140 console.log('测试log:onPaste') 4141 }) 4142 Text('测试文字去Hellow') 4143 .lineHeight(50) 4144 .fontSize(24) 4145 .draggable(true) 4146 .onDragStart(()=>{}) 4147 TextInput({text:'测试文字NiHao'}) 4148 .draggable(true) 4149 .margin(20) 4150 } 4151 } 4152} 4153``` 4154### 示例18(配置输入法enter键功能) 4155通过[enterKeyType](#enterkeytype12)属性设置软键盘输入法回车键类型。 4156 4157```ts 4158@Entry 4159@Component 4160struct SoftKeyboardEnterTypeExample { 4161 controller: RichEditorController = new RichEditorController() 4162 4163 build() { 4164 Column() { 4165 Button("停止编辑").onClick(()=>{ 4166 this.controller.stopEditing() 4167 }) 4168 RichEditor({ controller: this.controller }) 4169 .margin(10) 4170 .border({ width: 1 }) 4171 .height(200) 4172 .borderWidth(1) 4173 .borderColor(Color.Red) 4174 .width("100%") 4175 .enterKeyType(EnterKeyType.Search) 4176 .onSubmit((enterKey: EnterKeyType, event: SubmitEvent) => { 4177 console.log("trigger richeditor onsubmit" + enterKey); 4178 this.controller.addTextSpan(" type["+ enterKey +"] triggerred") 4179 event.keepEditableState(); 4180 }) 4181 }.height("100%").justifyContent(FlexAlign.Center) 4182 } 4183} 4184``` 4185 4186 4187 4188### 示例19(设置段落折行规则) 4189通过[updateParagraphStyle](#updateparagraphstyle11)接口设置折行类型([lineBreakStrategy](#richeditorparagraphstyle11)),通过[getParagraphs](#getparagraphs11)接口获取此时段落的折行类型。 4190 4191```ts 4192@Entry 4193@Component 4194struct LineBreakStrategyExample { 4195 controller: RichEditorController = new RichEditorController(); 4196 private spanParagraphs: RichEditorParagraphResult[] = []; 4197 @State lineBreakOptionStr: string[] = ['GREEDY', 'HIGH_QUALITY', 'BALANCED'] 4198 @State attributeValue: string = "" 4199 @State testStr: string = "0123456789,0123456789,0123456789,0123456789,0123456789." 4200 build() { 4201 Column() { 4202 RichEditor({ controller: this.controller }) 4203 .onReady(() => { 4204 this.controller.addTextSpan(this.testStr, { 4205 style: { 4206 fontColor: Color.Black, 4207 fontSize: "32", 4208 }, 4209 paragraphStyle: { 4210 textAlign: TextAlign.Start, 4211 lineBreakStrategy: LineBreakStrategy.GREEDY 4212 } 4213 }) 4214 }) 4215 .width(400) 4216 .height(300) 4217 .margin({bottom:20}) 4218 .draggable(false) 4219 Column(){ 4220 Text('linebreak属性值为:' + this.attributeValue).fontSize(20).fontColor(Color.Black) 4221 }.margin({bottom: 10}) 4222 Column({ space: 10 }) { 4223 Button("设置折行类型GREEDY").onClick(() => { 4224 this.controller.updateParagraphStyle({ start: -1, end: -1, 4225 style: { 4226 lineBreakStrategy: LineBreakStrategy.GREEDY, 4227 } 4228 }) 4229 }) 4230 Button("设置折行类型HIGH_QUALITY").onClick(() => { 4231 this.controller.updateParagraphStyle({ start: -1, end: -1, 4232 style: { 4233 lineBreakStrategy: LineBreakStrategy.HIGH_QUALITY, 4234 } 4235 }) 4236 }) 4237 Button("设置折行类型BALANCED").onClick(() => { 4238 this.controller.updateParagraphStyle({ start: -1, end: -1, 4239 style: { 4240 lineBreakStrategy: LineBreakStrategy.BALANCED, 4241 } 4242 }) 4243 }) 4244 Divider() 4245 Row(){ 4246 Button("获取linebreak属性值").onClick(() => { 4247 this.spanParagraphs = this.controller.getParagraphs({ start: -1, end: -1 }) 4248 console.log("RichEditor getParagraphs:" + JSON.stringify(this.spanParagraphs)) 4249 this.spanParagraphs.forEach(item => { 4250 if(typeof(item as RichEditorParagraphResult)['style'] != 'undefined'){ 4251 this.attributeValue = "" 4252 console.info('lineBreakStrategy:'+ JSON.stringify((item as RichEditorParagraphResult)['style'])) 4253 this.attributeValue += this.lineBreakOptionStr[Number((item as RichEditorParagraphResult)['style'].lineBreakStrategy)]; 4254 } 4255 }) 4256 }) 4257 } 4258 } 4259 } 4260 } 4261} 4262``` 4263 4264 4265 4266### 示例20(属性字符串基本功能) 4267[属性字符串](./ts-universal-styled-string.md)通过[RichEditorStyledStringController](#richeditorstyledstringcontroller12)中的[setStyledString](#setstyledstring12)方法与RichEditor组件绑定。通过[getStyledString](#getstyledstring12)接口获取富文本组件显示的属性字符串。 4268 4269```ts 4270// xxx.ets 4271import { LengthMetrics } from '@kit.ArkUI' 4272import { image } from '@kit.ImageKit' 4273 4274@Entry 4275@Component 4276struct Index { 4277 stringLength: number = 0; 4278 imagePixelMap: image.PixelMap | undefined = undefined; 4279 @State selection: string = ""; 4280 @State content: string = ""; 4281 @State range: string = ""; 4282 @State replaceString: string = ""; 4283 @State rangeBefore: string = ""; 4284 @State rangeAfter: string = ""; 4285 richEditorStyledString: MutableStyledString = new MutableStyledString(""); 4286 textStyle: TextStyle = new TextStyle({ 4287 fontWeight: FontWeight.Lighter, 4288 fontFamily: 'HarmonyOS Sans', 4289 fontColor: Color.Green, 4290 fontSize: LengthMetrics.vp(30), 4291 fontStyle: FontStyle.Normal 4292 }) 4293 fontStyle1: TextStyle = new TextStyle({ fontColor: Color.Blue }); 4294 fontStyle2: TextStyle = new TextStyle({ 4295 fontWeight: FontWeight.Bolder, 4296 fontFamily: 'Arial', 4297 fontColor: Color.Orange, 4298 fontSize: LengthMetrics.vp(30), 4299 fontStyle: FontStyle.Italic 4300 }) 4301 4302 controller1: RichEditorController = new RichEditorController() 4303 options1: RichEditorOptions = { controller: this.controller1 }; 4304 // 创建属性字符串对象 4305 mutableStyledString: MutableStyledString = new MutableStyledString("初始属性字符串", 4306 [{ start: 0, length: 5, styledKey: StyledStringKey.FONT, styledValue: this.fontStyle1 }]); 4307 styledString: StyledString = new StyledString("插入属性字符串", 4308 [{ start: 2, length: 4, styledKey: StyledStringKey.FONT, styledValue: this.fontStyle2 }]); 4309 controller: RichEditorStyledStringController = new RichEditorStyledStringController(); 4310 options: RichEditorStyledStringOptions = {controller: this.controller}; 4311 // 文本内容变化回调 4312 contentChangedListener: StyledStringChangedListener = { 4313 onWillChange: (value: StyledStringChangeValue) => { 4314 this.range = '[ ' + value.range.start + ' , ' + value.range.end + ' ]'; 4315 this.replaceString = value.replacementString.getString(); 4316 return true; 4317 }, 4318 onDidChange: (rangeBefore, rangeAfter) => { 4319 this.rangeBefore = '[ ' + rangeBefore.start + ' , ' + rangeBefore.end + ' ]'; 4320 this.rangeAfter = '[ ' + rangeAfter.start + ' , ' + rangeAfter.end + ' ]'; 4321 } 4322 } 4323 4324 async aboutToAppear() { 4325 console.info("aboutToAppear initial imagePixelMap"); 4326 this.imagePixelMap = await this.getPixmapFromMedia($r('app.media.app_icon')); 4327 } 4328 4329 private async getPixmapFromMedia(resource: Resource) { 4330 let unit8Array = await getContext(this)?.resourceManager?.getMediaContent({ 4331 bundleName: resource.bundleName, 4332 moduleName: resource.moduleName, 4333 id: resource.id 4334 }) 4335 let imageSource = image.createImageSource(unit8Array.buffer.slice(0, unit8Array.buffer.byteLength)) 4336 let createPixelMap: image.PixelMap = await imageSource.createPixelMap({ 4337 desiredPixelFormat: image.PixelMapFormat.RGBA_8888 4338 }) 4339 await imageSource.release() 4340 return createPixelMap 4341 } 4342 4343 4344 build() { 4345 Column({space:6}) { 4346 Column() { 4347 Text("选中区信息") 4348 .fontSize(20) 4349 .width("100%") 4350 Text("selection range: " + this.selection).width("100%") 4351 Text("selection content: " + this.content).width("100%") 4352 } 4353 .width("100%") 4354 .height("10%") 4355 4356 Column() { 4357 Text("onWillChange回调信息") 4358 .fontSize(20) 4359 .width("100%") 4360 Text("range: " + this.range).width("100%") 4361 Text("replacementString: " + this.replaceString).width("100%") 4362 Text("onWillChange回调信息") 4363 .fontSize(20) 4364 .width("100%") 4365 Text("rangeBefore: " + this.rangeBefore).width("100%") 4366 Text("rangeAfter: " + this.rangeAfter).width("100%") 4367 } 4368 .borderWidth(1) 4369 .borderColor(Color.Black) 4370 .width("100%") 4371 .height("20%") 4372 4373 RichEditor(this.options) 4374 .onReady(() => { 4375 // 注册文本变化回调 4376 this.controller.onContentChanged(this.contentChangedListener); 4377 // 设定组件展示的属性字符串 4378 this.controller.setStyledString(this.mutableStyledString); 4379 }) 4380 .height("20%") 4381 .width("100%") 4382 4383 RichEditor(this.options1) 4384 .onReady(() => { 4385 this.controller1.addTextSpan("把这些文字转换成属性字符串"); 4386 }) 4387 .height("10%") 4388 .width("100%") 4389 .borderWidth(1) 4390 .borderColor(Color.Black) 4391 4392 Row({space:2}) { 4393 Button("插入图片") 4394 .stateEffect(true) 4395 .onClick(() => { 4396 if (this.imagePixelMap !== undefined) { 4397 let imageStyledString = new MutableStyledString(new ImageAttachment({ 4398 value: this.imagePixelMap, 4399 size: { width: 50, height: 50 }, 4400 layoutStyle: { borderRadius: LengthMetrics.vp(10) }, 4401 verticalAlign: ImageSpanAlignment.BASELINE, 4402 objectFit: ImageFit.Contain 4403 })) 4404 // 获取组件展示的属性字符串 4405 this.richEditorStyledString = this.controller.getStyledString(); 4406 this.richEditorStyledString.appendStyledString(imageStyledString); 4407 // 使插入图片后的属性字符串展示在组件上 4408 this.controller.setStyledString(this.richEditorStyledString); 4409 this.controller.setCaretOffset(this.richEditorStyledString.length); 4410 } 4411 }) 4412 Button("插入文本").onClick(() => { 4413 // 获取组件展示的属性字符串 4414 this.richEditorStyledString = this.controller.getStyledString(); 4415 this.richEditorStyledString.appendStyledString(this.styledString); 4416 // 使插入文本后的属性字符串展示在组件上 4417 this.controller.setStyledString(this.richEditorStyledString); 4418 this.controller.setCaretOffset(this.richEditorStyledString.length); 4419 }) 4420 Button("删除选中内容").onClick(() => { 4421 // 获取选中范围 4422 let richEditorSelection = this.controller.getSelection(); 4423 let start = richEditorSelection.start ? richEditorSelection.start : 0; 4424 let end = richEditorSelection.end ? richEditorSelection.end : 0; 4425 if (start < 0 || end <= start) { 4426 return; 4427 } 4428 // 获取组件展示的属性字符串 4429 this.richEditorStyledString = this.controller.getStyledString(); 4430 this.richEditorStyledString.removeString(start, end - start); 4431 // 使删除内容后的属性字符串展示在组件上 4432 this.controller.setStyledString(this.richEditorStyledString); 4433 }) 4434 } 4435 Row({space:2}) { 4436 Button("获取选中内容").onClick(() => { 4437 // 获取选中范围 4438 let richEditorSelection = this.controller.getSelection(); 4439 let start = richEditorSelection.start ? richEditorSelection.start : 0; 4440 let end = richEditorSelection.end ? richEditorSelection.end : 0; 4441 // 获取组件展示的属性字符串 4442 this.richEditorStyledString = this.controller.getStyledString(); 4443 this.selection = '[ ' + start + ' , ' + end + ' ]'; 4444 if (start == end) { 4445 this.content = ""; 4446 } else { 4447 this.content = this.richEditorStyledString.subStyledString(start, end - start).getString(); 4448 } 4449 }) 4450 Button("更新选中样式").onClick(() => { 4451 // 获取选中范围 4452 let richEditorSelection = this.controller.getSelection(); 4453 let start = richEditorSelection.start ? richEditorSelection.start : 0; 4454 let end = richEditorSelection.end ? richEditorSelection.end : 0; 4455 if (start < 0 || end <= start) { 4456 return; 4457 } 4458 // 获取组件展示的属性字符串 4459 this.richEditorStyledString = this.controller.getStyledString(); 4460 this.richEditorStyledString.setStyle({ 4461 start: start, 4462 length: end - start, 4463 styledKey: StyledStringKey.FONT, 4464 styledValue: this.textStyle 4465 }) 4466 // 使变更样式后的属性字符串展示在组件上 4467 this.controller.setStyledString(this.richEditorStyledString); 4468 }) 4469 } 4470 Row({space:2}){ 4471 //将属性字符串转换成span信息 4472 Button("调用fromStyledString").onClick(() => { 4473 this.controller1.addTextSpan("调用fromStyledString:" +JSON.stringify(this.controller1.fromStyledString(this.mutableStyledString))) 4474 }) 4475 //将给定范围的组件内容转换成属性字符串 4476 Button("调用toStyledString").onClick(() => { 4477 this.controller.setStyledString(this.controller1.toStyledString({start:0,end:13})) 4478 }) 4479 } 4480 } 4481 } 4482} 4483``` 4484 4485.gif) 4486 4487### 示例21(获取布局信息) 4488通过[getLayoutManager](#getlayoutmanager12)接口获取布局管理器对象,通过[getLineCount](ts-text-common.md#getlinecount)接口获取组件内容的总行数,通过[getGlyphPositionAtCoordinate](ts-text-common.md#getglyphpositionatcoordinate)接口获取较为接近给定坐标的字形的位置信息,通过[getLineMetrics](ts-text-common.md#getlinemetrics)接口获取指定行的行信息、文本样式信息、以及字体属性信息。 4489 4490```ts 4491@Entry 4492@Component 4493export struct Index { 4494 @State lineCount: string = "" 4495 @State glyphPositionAtCoordinate: string = "" 4496 @State lineMetrics: string = "" 4497 controller: RichEditorController = new RichEditorController(); 4498 @State textStr: string = 4499 'Hello World! 你好,世界!' 4500 4501 build() { 4502 Scroll() { 4503 Column() { 4504 Text('RichEditor组件getLayoutManager接口获取相对于组件的布局信息') 4505 .fontSize(9) 4506 .fontColor(0xCCCCCC) 4507 .width('90%') 4508 .padding(10) 4509 RichEditor({ controller: this.controller }) 4510 .borderColor(Color.Red) 4511 .borderWidth(1) 4512 .onReady(() => { 4513 this.controller.addTextSpan(this.textStr) 4514 }) 4515 .onAreaChange(() => { 4516 let layoutManager = this.controller.getLayoutManager(); 4517 this.lineCount = "LineCount: " + layoutManager.getLineCount() 4518 }) 4519 4520 Text('LineCount').fontSize(9).fontColor(0xCCCCCC).width('90%').padding(10) 4521 Text(this.lineCount) 4522 4523 Text('GlyphPositionAtCoordinate').fontSize(9).fontColor(0xCCCCCC).width('90%').padding(10) 4524 Button("相对组件坐标[150,50]字形信息") 4525 .onClick(() => { 4526 let layoutManager: LayoutManager = this.controller.getLayoutManager() 4527 let position = layoutManager.getGlyphPositionAtCoordinate(150, 50) 4528 this.glyphPositionAtCoordinate = 4529 "相对组件坐标[150,50] glyphPositionAtCoordinate position: " + position.position + " affinity: " + 4530 position.affinity 4531 }) 4532 .margin({ bottom: 20, top: 10 }) 4533 Text(this.glyphPositionAtCoordinate) 4534 4535 Text('LineMetrics').fontSize(9).fontColor(0xCCCCCC).width('90%').padding(10) 4536 Button("首行行信息、文本样式信息、以及字体属性信息") 4537 .onClick(() => { 4538 let layoutManager: LayoutManager = this.controller.getLayoutManager() 4539 let lineMetrics = layoutManager.getLineMetrics(0) 4540 this.lineMetrics = "lineMetrics is " + JSON.stringify(lineMetrics) + '\n\n' 4541 let runMetrics = lineMetrics.runMetrics 4542 runMetrics.forEach((value, key) => { 4543 this.lineMetrics += "runMetrics key is " + key + " " + JSON.stringify(value) + "\n\n" 4544 }); 4545 }) 4546 .margin({ bottom: 20, top: 10 }) 4547 Text(this.lineMetrics) 4548 } 4549 .margin({ top: 100, left: 8, right: 8 }) 4550 } 4551 } 4552} 4553``` 4554 4555 4556 4557### 示例22(设置自定义菜单扩展项) 4558通过[editMenuOptions](#editmenuoptions12)属性设置自定义菜单扩展项,允许用户设置扩展项的文本内容、图标、回调方法。 4559 4560```ts 4561// xxx.ets 4562@Entry 4563@Component 4564struct RichEditorExample { 4565 controller: RichEditorController = new RichEditorController(); 4566 options: RichEditorOptions = { controller: this.controller } 4567 4568 onCreateMenu(menuItems: Array<TextMenuItem>) { 4569 console.log('menuItems size=' + menuItems.length); 4570 menuItems.forEach((value, index) => { 4571 console.log('menuItem' + index + ', id=' + JSON.stringify(value)); 4572 }) 4573 let extensionMenuItems: Array<TextMenuItem> = [ 4574 { 4575 content: 'RichEditor扩展1', icon: $r('app.media.startIcon'), id: TextMenuItemId.of('extension1') 4576 }, 4577 { 4578 content: 'RichEditor扩展2', icon: $r('app.media.startIcon'), id: TextMenuItemId.of('extension2') 4579 }, 4580 { 4581 content: 'RichEditor扩展3', icon: $r('app.media.startIcon'), id: TextMenuItemId.of('extension3') 4582 }, 4583 { 4584 content: 'RichEditor扩展4', icon: $r('app.media.startIcon'), id: TextMenuItemId.of('extension4') 4585 } 4586 ] 4587 return menuItems.concat(extensionMenuItems) 4588 } 4589 onMenuItemClicked(menuItem: TextMenuItem, textRange: TextRange) { 4590 if (menuItem.id.equals(TextMenuItemId.of('extension1'))) { 4591 console.log('click' + menuItem.content + ', textRange=' + JSON.stringify(textRange)) 4592 return true; 4593 } 4594 return false; 4595 } 4596 4597 build() { 4598 Row() { 4599 RichEditor(this.options) 4600 .onReady(() => { 4601 this.controller.addTextSpan("RichEditor扩展") 4602 }) 4603 .editMenuOptions({ 4604 onCreateMenu: (menuItems: Array<TextMenuItem>) => { 4605 return this.onCreateMenu(menuItems) 4606 }, 4607 onMenuItemClick: (menuItem: TextMenuItem, textRange: TextRange) => { 4608 return this.onMenuItemClicked(menuItem, textRange) 4609 } 4610 }) 4611 .height(200) 4612 .borderWidth(1) 4613 .borderColor(Color.Red) 4614 } 4615 } 4616} 4617``` 4618 4619 4620 4621### 示例23(组件部分常用属性) 4622通过[barState](#barstate13)属性设置组件编辑态时滚动条的显示模式。通过[enableKeyboardOnFocus](#enablekeyboardonfocus12)属性设置组件通过点击以外的方式获焦时,是否主动拉起软键盘。通过[enableHapticFeedback](#enablehapticfeedback13)属性设置组件是否支持触控反馈。通过[getPreviewText](#getpreviewtext12)接口获取组件预上屏信息。 4623 4624```ts 4625// xxx.ets 4626import { JSON } from '@kit.ArkTS'; 4627 4628@Entry 4629@Component 4630struct RichEditor_example { 4631 controller: RichEditorController = new RichEditorController() 4632 options: RichEditorOptions = { controller: this.controller }; 4633 4634 controller1: RichEditorController = new RichEditorController() 4635 options1: RichEditorOptions = { controller: this.controller1 }; 4636 4637 @State e: boolean = true 4638 @State bs_num: number = 0 4639 @State bs: (BarState | undefined)[] = [BarState.Auto, BarState.On, BarState.Off, undefined] 4640 @State bs_string: (String)[] = ["Auto", "On", "Off", "undefined"] 4641 4642 build() { 4643 Column({space: 3}) { 4644 RichEditor(this.options) 4645 .onReady(() => { 4646 this.controller.addTextSpan('文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本', { 4647 style: { 4648 fontColor: Color.Black, 4649 fontSize: 15 4650 } 4651 }) 4652 }) 4653 .onDidIMEInput((value: TextRange) => { 4654 this.controller1.addTextSpan("\n" + "触发了onDidIMEInput回调,输入法本次输入内容范围为:(" + value.start + "," + value.end + ")", { 4655 style: { 4656 fontColor: Color.Gray, 4657 fontSize: 10 4658 } 4659 }) 4660 }) 4661 .onSelectionChange((value: RichEditorRange) => { 4662 this.controller1.addTextSpan("\n" + "触发了onSelectionChange回调,起始范围信息为:(" + value.start + "," + value.end + ")", { 4663 style: { 4664 fontColor: Color.Gray, 4665 fontSize: 10 4666 } 4667 }) 4668 }) 4669 .width(300) 4670 .height(100) 4671 .margin(20) 4672 .barState(this.bs[this.bs_num]) 4673 .enableKeyboardOnFocus(this.e) 4674 .enableHapticFeedback(true) 4675 4676 RichEditor(this.options1).width(300) 4677 4678 Button('设置barState为:' + this.bs_string[this.bs_num]) 4679 .height(30) 4680 .fontSize(13) 4681 .onClick(() => { 4682 this.bs_num++ 4683 if (this.bs_num > (this.bs.length - 1)) { 4684 this.bs_num = 0 4685 } 4686 }) 4687 4688 Button('设置enableKeyboardOnFocus为:' + this.e) 4689 .height(30) 4690 .fontSize(13) 4691 .onClick(() => { 4692 this.e = !this.e 4693 }) 4694 4695 Button('获取预上屏信息') 4696 .height(30) 4697 .fontSize(13) 4698 .onClick(() => { 4699 this.controller1.addTextSpan("\n获取预上屏信息:" + JSON.stringify(this.controller.getPreviewText())) 4700 }) 4701 } 4702 } 4703} 4704 4705``` 4706 4707