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