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