Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
Docs
提交
a1a100c6
D
Docs
项目概览
OpenHarmony
/
Docs
1 年多 前同步成功
通知
159
Star
292
Fork
28
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
Docs
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
a1a100c6
编写于
8月 31, 2023
作者:
O
openharmony_ci
提交者:
Gitee
8月 31, 2023
浏览文件
操作
浏览文件
下载
差异文件
!23622 add richEditor selectionMenu and copyOption content
Merge pull request !23622 from lukewang1/cherry-pick-1693475574
上级
03b3b5cf
146897d1
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
386 addition
and
4 deletion
+386
-4
zh-cn/application-dev/reference/arkui-ts/figures/richEditorSelectionMenu.png
...ev/reference/arkui-ts/figures/richEditorSelectionMenu.png
+0
-0
zh-cn/application-dev/reference/arkui-ts/ts-basic-components-richeditor.md
...-dev/reference/arkui-ts/ts-basic-components-richeditor.md
+386
-4
未找到文件。
zh-cn/application-dev/reference/arkui-ts/figures/richEditorSelectionMenu.png
0 → 100644
浏览文件 @
a1a100c6
33.4 KB
zh-cn/application-dev/reference/arkui-ts/ts-basic-components-richeditor.md
浏览文件 @
a1a100c6
...
...
@@ -33,9 +33,9 @@ RichEditor(value: RichEditorOptions)
| 名称 | 参数类型 | 描述 |
| ------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
| customKeyboard
<sup>
10+
</sup>
|
[
CustomBuilder
](
ts-types.md#custombuilder8
)
| 设置自定义键盘。
<br/>
**说明:**
<br/>
当设置自定义键盘时,输入框激活后不会打开系统输入法,而是加载指定的自定义组件。
<br/>
自定义键盘的高度可以通过自定义组件根节点的height属性设置,宽度不可设置,使用系统默认值。
<br/>
自定义键盘采用覆盖原始界面的方式呈现,不会对应用原始界面产生压缩或者上提。
<br/>
自定义键盘无法获取焦点,但是会拦截手势事件。
<br/>
默认在输入控件失去焦点时,关闭自定义键盘。 |
| customKeyboard |
[
CustomBuilder
](
ts-types.md#custombuilder8
)
| 设置自定义键盘。
<br/>
**说明:**
<br/>
当设置自定义键盘时,输入框激活后不会打开系统输入法,而是加载指定的自定义组件。
<br/>
自定义键盘的高度可以通过自定义组件根节点的height属性设置,宽度不可设置,使用系统默认值。
<br/>
自定义键盘采用覆盖原始界面的方式呈现,不会对应用原始界面产生压缩或者上提。
<br/>
自定义键盘无法获取焦点,但是会拦截手势事件。
<br/>
默认在输入控件失去焦点时,关闭自定义键盘。 |
| bindSelectionMenu | {
<br/>
spantype:
[RichEditorSpanType](#richeditorspantype),
<br/>
content:
[CustomBuilder](ts-types.md#custombuilder8),
<br/>
responseType:
[ResponseType](ts-appendix-enums.md#responsetype8),
<br/>
options?:
[
SelectionMenuOptions
](
#selectionmenuoptions
)
<br/>
} | 设置自定义选择菜单。
<br/>
默认值:{
<br/>
spanType:
RichEditorSpanType:TEXT
<br/>
responseType:
ResponseType.LongPress
<br/>
其他:空
<br/>
}
<br/>
**说明:**
<br/>
当前spanType参数设置不会生效,不区分类型。|
| copyOption |
[
CopyOptions
](
ts-appendix-enums.md#copyoptions9
)
| 组件支持设置内容是否可复制粘贴。
<br
/>
默认值:CopyOptions.LocalDevice
<br/>
**说明:**
<br/>
设置copyOptions为CopyOptions.InApp或者CopyOptions.LocalDevice,长按组件内容,会弹出文本默认选择菜单,可选中内容并进行复制、全选操作。
<br/>
设置copyOptions为CopyOptions.None,复制、剪切功能不生效。 |
## 事件
除支持
[
通用事件
](
ts-universal-events-click.md
)
外,还支持以下事件:
...
...
@@ -100,6 +100,16 @@ Span位置信息。
| spanIndex | number | 是 | Span索引值。 |
| spanRange | [number, number] | 是 | Span内容在RichEditor内的起始和结束位置。 |
## RichEditorSpanType
Span类型信息。
| 名称 | 类型 | 必填 | 说明 |
| -------- | -------- | -------- | -------- |
| TEXT | number | 是 | Span为文字类型。 |
| IMAGE | number | 是 | Span为图像类型。|
| MIXED | number | 是 | Span为图文混合类型。|
## RichEditorTextStyleResult
...
...
@@ -257,6 +267,11 @@ deleteSpans(value?: RichEditorRange): void
| ------ | -------- | ---- | -------------------------------------- |
| value |
[
RichEditorRange
](
#richeditorrange
)
| 否 | 删除范围。省略时,删除所有文本和图片。|
### closeSelectionMenu
closeSelectionMenu(): void
关闭自定义选择菜单或系统默认选择菜单。
## RichEditorSelection
...
...
@@ -341,6 +356,15 @@ deleteSpans(value?: RichEditorRange): void
| start | number | 否 | 起始位置,省略或者设置负值时表示从0开始。 |
| end | number | 否 | 结束位置,省略或者超出文本范围时表示到结尾。 |
## SelectionMenuOptions
范围信息。
| 名称 | 类型 | 必填 | 描述 |
| ------ | -------- | ---- | -------------------------------------- |
| onAppear | ?(() => void) | 否 | 自定义选择菜单弹出时回调。 |
| onDisappear | ?(() => void) | 否 | 自定义选择菜单关闭时回调。 |
## 示例
...
...
@@ -538,4 +562,362 @@ struct RichEditorExample {
}
```
![
customKeyboard
](
figures/richEditorCustomKeyboard.png
)
\ No newline at end of file
![
customKeyboard
](
figures/richEditorCustomKeyboard.png
)
### 示例3
```
ts
// xxx.ets
import
pasteboard
from
'
@ohos.pasteboard
'
@
Entry
@
Component
struct
SelectionMenu
{
@
State
message
:
string
=
'
Hello World
'
@
State
textSize
:
number
=
40
@
State
sliderShow
:
boolean
=
false
@
State
start
:
number
=
-
1
@
State
end
:
number
=
-
1
@
State
colorTransparent
:
Color
=
Color
.
Transparent
controller
:
RichEditorController
=
new
RichEditorController
();
options
:
RichEditorOptions
=
{
controller
:
this
.
controller
}
private
iconArr
:
Array
<
Resource
>
=
[
$r
(
'
app.media.icon
'
),
$r
(
"
app.media.icon
"
),
$r
(
'
app.media.icon
'
),
$r
(
"
app.media.icon
"
),
$r
(
'
app.media.icon
'
)]
private
listArr
:
Array
<
{
imageSrc
:
Resource
,
id
:
string
,
label
:
string
}
>
=
[{
imageSrc
:
$r
(
'
sys.media.ohos_ic_public_cut
'
),
id
:
'
剪切
'
,
label
:
"
Ctrl+X
"
},
{
imageSrc
:
$r
(
'
sys.media.ohos_ic_public_copy
'
),
id
:
'
复制
'
,
label
:
"
Ctrl+C
"
},
{
imageSrc
:
$r
(
'
sys.media.ohos_ic_public_paste
'
),
id
:
'
粘贴
'
,
label
:
"
Ctrl+V
"
},
{
imageSrc
:
$r
(
'
sys.media.ohos_ic_public_select_all
'
),
id
:
'
全选
'
,
label
:
"
Ctrl+A
"
},
{
imageSrc
:
$r
(
'
sys.media.ohos_ic_public_share
'
),
id
:
'
分享
'
,
label
:
""
},
{
imageSrc
:
$r
(
'
sys.media.ohos_ic_public_translate_c2e
'
),
id
:
'
翻译
'
,
label
:
""
},
{
imageSrc
:
$r
(
'
sys.media.ohos_ic_public_search_filled
'
),
id
:
'
搜索
'
,
label
:
""
}]
@
State
iconBgColor
:
ResourceColor
[]
=
new
Array
(
this
.
iconArr
.
length
).
fill
(
this
.
colorTransparent
)
@
State
listBgColor
:
ResourceColor
[]
=
new
Array
(
this
.
listArr
.
length
).
fill
(
this
.
colorTransparent
)
@
State
iconIsFocus
:
boolean
[]
=
new
Array
(
this
.
iconArr
.
length
).
fill
(
false
)
@
State
listIsFocus
:
boolean
[]
=
new
Array
(
this
.
iconArr
.
length
).
fill
(
false
)
@
State
clickWeightNum
:
number
=
0
@
State
clickNum
:
number
[]
=
[
0
,
0
,
0
]
build
()
{
Column
()
{
Column
()
{
RichEditor
(
this
.
options
)
.
onReady
(()
=>
{
this
.
controller
.
addTextSpan
(
this
.
message
,
{
style
:
{
fontColor
:
Color
.
Orange
,
fontSize
:
30
}
})
})
.
onSelect
((
value
:
RichEditorSelection
)
=>
{
if
(
value
.
selection
==
[
-
1
.
-
1
])
return
[
this
.
start
,
this
.
end
]
=
value
.
selection
})
.
bindSelectionMenu
(
RichEditorSpanType
.
TEXT
,
this
.
panel
(),
ResponseType
.
LongPress
,
{
onDisappear
:
()
=>
{
this
.
sliderShow
=
false
}})
.
borderWidth
(
1
)
.
borderColor
(
Color
.
Red
)
.
width
(
200
)
.
height
(
200
)
.
position
({
x
:
150
,
y
:
100
})
}.
width
(
'
100
'
).
backgroundColor
(
Color
.
White
)
}.
height
(
'
100
'
)
}
@
Builder
panel
()
{
Column
()
{
Menu
()
{
MenuItem
({
builder
:
this
.
iconPanel
()
})
}.
shadow
(
ShadowStyle
.
OUTER_DEFAULT_MD
).
margin
({
bottom
:
8
})
Menu
()
{
if
(
!
this
.
sliderShow
)
{
MenuItem
({
builder
:
this
.
listPanel
()
})
}
else
{
MenuItem
({
builder
:
this
.
sliderPanel
()
})
}
}
.
backgroundColor
(
Color
.
Transparent
).
focusable
(
true
).
shadow
(
ShadowStyle
.
OUTER_DEFAULT_MD
)
}
}
@
Builder
iconPanel
()
{
Column
()
{
Row
({
space
:
2
})
{
ForEach
(
this
.
iconArr
,
(
item
,
index
)
=>
{
Flex
({
justifyContent
:
FlexAlign
.
SpaceBetween
,
alignItems
:
ItemAlign
.
Center
})
{
Image
(
item
).
fillColor
(
$r
(
'
sys.color.ohos_id_color_primary
'
)).
width
(
24
).
height
(
24
).
focusable
(
true
)
}
.
border
({
width
:
this
.
iconIsFocus
[
index
]
?
2
:
0
,
color
:
$r
(
'
sys.color.ohos_id_color_focused_outline
'
)
})
.
borderRadius
(
$r
(
'
sys.float.ohos_id_corner_radius_default_m
'
))
.
width
(
48
)
.
height
(
48
)
.
focusable
(
true
)
.
focusOnTouch
(
true
)
.
onClick
(()
=>
{
if
(
index
==
0
)
{
this
.
clickNum
[
0
]
++
this
.
sliderShow
=
false
this
.
controller
.
updateSpanStyle
({
start
:
this
.
start
,
end
:
this
.
end
,
textStyle
:
{
fontWeight
:
this
.
clickNum
[
0
]
%
2
!==
0
?
FontWeight
.
Bolder
:
FontWeight
.
Normal
}
})
}
else
if
(
index
==
1
)
{
this
.
clickNum
[
1
]
++
this
.
sliderShow
=
false
this
.
controller
.
updateSpanStyle
({
start
:
this
.
start
,
end
:
this
.
end
,
textStyle
:
{
fontStyle
:
this
.
clickNum
[
1
]
%
2
!==
0
?
FontStyle
.
Italic
:
FontStyle
.
Normal
}
})
}
else
if
(
index
==
2
)
{
this
.
clickNum
[
2
]
++
this
.
sliderShow
=
false
this
.
controller
.
updateSpanStyle
({
start
:
this
.
start
,
end
:
this
.
end
,
textStyle
:
{
decoration
:
{
type
:
this
.
clickNum
[
2
]
%
2
!==
0
?
TextDecorationType
.
Underline
:
TextDecorationType
.
None
}
}
})
}
else
if
(
index
==
3
)
{
this
.
sliderShow
=
!
this
.
sliderShow
}
else
if
(
index
==
4
)
{
this
.
sliderShow
=
false
}
})
.
onTouch
((
event
:
TouchEvent
)
=>
{
if
(
event
.
type
===
TouchType
.
Down
)
{
this
.
iconBgColor
[
index
]
=
$r
(
'
sys.color.ohos_id_color_click_effect
'
)
}
if
(
event
.
type
===
TouchType
.
Up
)
{
this
.
iconBgColor
[
index
]
=
this
.
colorTransparent
}
})
.
onHover
((
isHover
:
boolean
)
=>
{
this
.
iconBgColor
.
forEach
((
icon
,
index1
)
=>
{
this
.
iconBgColor
[
index1
]
=
this
.
colorTransparent
})
isHover
?
this
.
iconBgColor
[
index
]
=
$r
(
'
sys.color.ohos_id_color_hover
'
)
:
this
.
listBgColor
[
index
]
=
this
.
colorTransparent
})
.
onFocus
(()
=>
{
this
.
iconIsFocus
[
index
]
=
true
})
.
onBlur
(()
=>
{
this
.
iconIsFocus
[
index
]
=
false
})
.
backgroundColor
(
this
.
iconBgColor
[
index
])
})
}
}
.
backgroundColor
(
this
.
colorTransparent
)
.
borderRadius
(
$r
(
'
sys.float.ohos_id_corner_radius_card
'
))
.
width
(
256
)
.
height
(
56
)
.
padding
(
4
)
}
@
Builder
listPanel
()
{
Column
()
{
List
({
space
:
0
,
initialIndex
:
0
})
{
ForEach
(
this
.
listArr
,
(
item
,
index
)
=>
{
ListItem
()
{
listChild
({
item
,
index
,
listBgColor
:
$listBgColor
,
colorTransparent
:
$colorTransparent
})
.
onClick
(()
=>
{
let
sysBoard
=
pasteboard
.
getSystemPasteboard
()
this
.
controller
.
closeSelectionMenu
()
let
pasteData
=
pasteboard
.
createData
(
pasteboard
.
MIMETYPE_TEXT_PLAIN
,
''
)
this
.
controller
.
getSpans
({
start
:
this
.
start
,
end
:
this
.
end
})
.
forEach
((
item
,
i
)
=>
{
if
(
"
imageStyle
"
in
item
)
{
var
style
=
item
.
imageStyle
let
data
=
pasteboard
.
createRecord
(
pasteboard
.
MIMETYPE_PIXELMAP
,
item
.
valuePixelMap
)
let
prop
=
pasteData
.
getProperty
()
prop
.
additions
[
i
]
=
{
'
width
'
:
style
.
size
[
0
],
'
height
'
:
style
.
size
[
1
],
'
fit
'
:
style
.
objectFit
}
pasteData
.
addRecord
(
data
)
pasteData
.
setProperty
(
prop
)
}
else
{
let
style
=
item
.
textStyle
let
data
=
pasteboard
.
createRecord
(
pasteboard
.
MIMETYPE_TEXT_PLAIN
,
item
.
value
)
let
prop
=
pasteData
.
getProperty
()
prop
.
additions
[
i
]
=
{
'
color
'
:
style
.
fontColor
,
'
size
'
:
style
.
fontSize
,
'
style
'
:
style
.
fontStyle
,
'
weight
'
:
style
.
fontWeight
}
pasteData
.
addRecord
(
data
)
pasteData
.
setProperty
(
prop
)
}
})
switch
(
index
)
{
case
0
:
this
.
controller
.
deleteSpans
({
start
:
this
.
start
,
end
:
this
.
end
})
case
1
:
sysBoard
.
clearData
()
sysBoard
.
setData
(
pasteData
).
then
(()
=>
{
console
.
info
(
'
Succeeded in setting PasteData.
'
);
}).
catch
((
err
)
=>
{
console
.
error
(
'
Failed to set PasteData. Cause:
'
+
err
.
message
);
})
break
case
2
:
sysBoard
.
getData
((
err
,
data
)
=>
{
if
(
err
)
{
return
}
var
count
=
data
.
getRecordCount
()
for
(
let
m
=
0
;
m
<
count
;
m
++
)
{
const
element
=
data
.
getRecord
(
m
);
let
tex
:
RichEditorTextStyle
=
{
fontSize
:
30
,
fontColor
:
Color
.
Orange
,
fontWeight
:
FontWeight
.
Normal
}
let
im
:
RichEditorImageSpanStyle
=
{
objectFit
:
ImageFit
.
Contain
,
size
:
[
50
,
50
]
}
if
(
data
.
getProperty
().
additions
[
m
])
{
const
entry
=
Object
.
entries
(
data
.
getProperty
().
additions
[
m
])
for
(
let
[
key
,
value
]
of
entry
)
{
switch
(
key
)
{
case
'
width
'
:
im
.
size
[
0
]
=
value
continue
case
'
height
'
:
im
.
size
[
1
]
=
value
continue
case
'
fit
'
:
im
.
objectFit
=
value
continue
case
'
color
'
:
tex
.
fontColor
=
value
continue
case
'
size
'
:
tex
.
fontSize
=
value
continue
case
'
style
'
:
tex
.
fontStyle
=
value
continue
case
'
weight
'
:
tex
.
fontWeight
=
value
}
}
}
if
(
element
.
mimeType
==
pasteboard
.
MIMETYPE_TEXT_PLAIN
)
{
this
.
controller
.
addTextSpan
(
element
.
plainText
,
{
style
:
tex
,
offset
:
this
.
controller
.
getCaretOffset
()
})
}
if
(
element
.
mimeType
==
pasteboard
.
MIMETYPE_PIXELMAP
)
{
this
.
controller
.
addImageSpan
(
element
.
pixelMap
,
{
imageStyle
:
im
,
offset
:
this
.
controller
.
getCaretOffset
()
})
}
}
})
break
case
3
:
// 全选
}
})
}
.
height
(
48
)
.
borderRadius
(
$r
(
'
sys.float.ohos_id_corner_radius_card
'
))
.
focusable
(
true
)
.
focusOnTouch
(
true
)
.
border
({
width
:
this
.
listIsFocus
[
index
]
?
2
:
0
,
color
:
$r
(
'
sys.color.ohos_id_color_focused_outline
'
)
})
.
onFocus
(()
=>
{
this
.
listIsFocus
[
index
]
=
true
})
.
onBlur
(()
=>
{
this
.
listIsFocus
[
index
]
=
false
})
},
item
=>
item
)
}
}
.
focusable
(
true
)
.
width
(
256
)
.
padding
(
4
)
.
backgroundColor
(
this
.
colorTransparent
)
.
borderRadius
(
$r
(
'
sys.float.ohos_id_corner_radius_card
'
))
}
@
Builder
sliderPanel
()
{
Column
()
{
Flex
({
justifyContent
:
FlexAlign
.
SpaceBetween
,
alignItems
:
ItemAlign
.
Center
})
{
Text
(
'
A
'
).
fontSize
(
15
)
Slider
({
value
:
this
.
textSize
,
step
:
10
,
style
:
SliderStyle
.
InSet
})
.
width
(
210
)
.
onChange
((
value
:
number
,
mode
:
SliderChangeMode
)
=>
{
this
.
textSize
=
value
this
.
controller
.
updateSpanStyle
({
start
:
this
.
start
,
end
:
this
.
end
,
textStyle
:
{
fontSize
:
this
.
textSize
}
})
})
Text
(
'
A
'
).
fontSize
(
20
).
fontWeight
(
FontWeight
.
Medium
)
}.
borderRadius
(
$r
(
'
sys.float.ohos_id_corner_radius_card
'
))
}
.
backgroundColor
(
this
.
colorTransparent
)
.
borderRadius
(
$r
(
'
sys.float.ohos_id_corner_radius_card
'
))
.
padding
(
15
)
.
width
(
256
)
.
height
(
56
)
.
margin
({
bottom
:
8
})
}
}
@
Component
struct
listChild
{
item
index
@
Link
listBgColor
:
(
Resource
|
Color
)[]
@
Link
colorTransparent
:
Resource
build
()
{
Column
()
{
Flex
({
direction
:
FlexDirection
.
Row
,
justifyContent
:
FlexAlign
.
SpaceBetween
,
alignItems
:
ItemAlign
.
Center
})
{
Row
()
{
Image
(
this
.
item
.
imageSrc
)
.
width
(
20
)
.
height
(
20
)
.
margin
({
right
:
8
})
.
fillColor
(
$r
(
'
sys.color.ohos_id_color_primary
'
))
.
focusable
(
true
)
Text
(
''
+
this
.
item
.
id
)
.
textAlign
(
TextAlign
.
Center
)
.
borderRadius
(
10
)
.
focusable
(
true
)
.
fontColor
(
$r
(
'
sys.color.ohos_id_color_primary
'
))
.
fontSize
(
$r
(
'
sys.float.ohos_id_text_size_body1
'
))
}
Row
()
{
Text
(
''
+
this
.
item
.
label
)
.
fontColor
(
$r
(
'
sys.color.ohos_id_color_text_secondary
'
)).
fontSize
(
$r
(
'
sys.float.ohos_id_text_size_body1
'
))
}
}
.
onTouch
((
event
:
TouchEvent
)
=>
{
if
(
event
.
type
===
TouchType
.
Down
)
{
this
.
listBgColor
[
this
.
index
]
=
$r
(
'
sys.color.ohos_id_color_click_effect
'
)
}
if
(
event
.
type
===
TouchType
.
Up
)
{
this
.
listBgColor
[
this
.
index
]
=
this
.
colorTransparent
}
})
.
onHover
((
isHover
:
boolean
)
=>
{
this
.
listBgColor
[
this
.
index
]
=
isHover
?
$r
(
'
sys.color.ohos_id_color_hover
'
)
:
this
.
colorTransparent
})
.
backgroundColor
(
this
.
listBgColor
[
this
.
index
])
.
padding
({
right
:
12
,
left
:
12
})
.
height
(
'
48
'
)
.
focusable
(
true
)
.
borderRadius
(
$r
(
'
sys.float.ohos_id_corner_radius_default_m
'
))
}
}
}
```
![
selectionMenu
](
figures/richEditorSelectionMenu.png
)
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录