智能客服
你问我答,随时在线为你解决问题
如何对Text组件绑定长按手势,实现文本内容全选并弹出自定义菜单的功能?
Text组件用于显示一段文本的组件,可以包含文字、图片等。该组件提供了bindSelectionMenu接口用于设置自定义选择菜单。bindSelectionMenu长按响应时长为600ms,长按达到时长后弹出自定义菜单。为了触发组件长按手势,可为组件绑定LongPressGesture事件,触发长按手势的最少手指数为1,最短长按时间若不设置,默认值为500毫秒。即达到500毫秒或者自定义时间时,会触发手势回调。
代码实现如下:
- @Entry
- @Component
- struct TextExample {
- optionsPopup: string[] = ['搜索', '复制', '粘贴'];
- controller: TextController = new TextController();
- options: TextOptions = { controller: this.controller };
- @State start: number = -1; // 选中区域开始光标
- @State end: number = -1; // 选中区域结束光标
-
- build() {
- Column() {
- Column() {
- Text(undefined, this.options) {
- // 将Text内容设置为字图混合形式
- Span('Hello World')
- .fontSize(36)
- ImageSpan($r('app.media.startIcon'))
- .width('120px')
- .height('120px')
- .objectFit(ImageFit.Fill)
- .verticalAlign(ImageSpanAlignment.CENTER);
- }
- .selection(this.start, this.end) // 选中区域
- .copyOption(CopyOptions.InApp) // 设置可复制
- .bindSelectionMenu(TextSpanType.DEFAULT, this.LongPressTextCustomMenu, TextResponseType.DEFAULT) // 自定义菜单
- .gesture(
- LongPressGesture({ duration: 300 })
- .onAction(() => {
- // 调整选中区域,全选文本
- this.start = 0;
- this.end = 12;
- })
- )
- .width('100%')
- .height(150);
- }
- .width('100%')
- .backgroundColor(Color.White)
- .alignItems(HorizontalAlign.Start)
- .padding(25);
- }
- .height('100%');
- }
-
- // 自定义菜单
- @Builder
- LongPressTextCustomMenu() {
- Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.SpaceEvenly, alignItems: ItemAlign.Center }) {
- ForEach(this.optionsPopup, (item: string, index) => {
- Text(item).height('100%')
- .onClick(() => {
- // 取消选中
- this.start = -1;
- this.end = -1;
- // 关闭自定义菜单
- this.controller.closeSelectionMenu();
- });
- // 设置间隔
- if (index < this.optionsPopup.length - 1) {
- Divider().height(10).vertical(true);
- }
- });
- }
- .width(150)
- .height(40)
- .padding(10)
- .shadow({
- radius: 20,
- color: '#f3f5f7',
- offsetX: 0,
- offsetY: 10
- })
- .borderRadius(20)
- }
- }
运行效果如下:

Q:为什么不使用onAppear做弹出菜单前的全选或者onDisappear做关闭菜单后的取消选中操作?
A:菜单的重新生成会触发onAppear和onDisappear,重新生成的场景包括选中区域文本类型的变化(由纯文字变为图文混合等)。因此当拖动光标触发上述场景,onAppear会导致选中区域强制为全选,onDisappear会导致选中区域强制取消,不符合交互逻辑。
Q:为什么将responseType为TextResponseType.LONG_PRESS,长按后弹出系统菜单,滑动光标后变为自定义菜单?
A:通过section设置的光标滑动,会被认为是TextResponseType.SELECT,因此会触发系统菜单。滑动过程中需要手指长按,因此被识别为长按,唤起自定义菜单。
Q:点击文本外的按钮触发弹窗事件,Text的文本选中菜单消失了但是不走onDisappear回调,是什么原因?
A:系统弹窗弹出,文本菜单消失,只是隐藏了,依旧在组件树上,并没有销毁,不会走onDisappear回调,会触发onMenuHide事件。
Q:RichText是否能使用自定义菜单?
A:RichText无法通过自定义菜单控制文本选择,推荐使用Web组件或者使用RichEditor组件,禁用编辑功能和键盘,再实现自定义菜单。
Q:如何给TextInput的复制粘贴功能添加自定义功能点?
A:可以使用editMenuOptions设置自定义菜单扩展项。参考示例文本扩展自定义菜单。
Q:Text组件内自定义Span无法添加点击事件,如何实现点击文本弹出菜单的功能?
A:通过onTextSelectionChange()方法来实现,根据选中的文本弹出菜单,文本选择的位置发生变化时,触发该回调。详情可参考官网:示例8(文本绑定自定义菜单)。