• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 菜单控制
2
3为组件绑定弹出式菜单,弹出式菜单以垂直列表形式显示菜单项,可通过长按、点击或鼠标右键触发。
4
5>  **说明:**
6>
7>  - 从API Version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。
8>
9>  - CustomBuilder里不支持再使用bindMenu、bindContextMenu弹出菜单。多级菜单可使用[Menu组件](ts-basic-components-menu.md)。
10>
11>  - 弹出菜单的文本内容不支持长按选中。
12
13
14## 属性
15
16
17| 名称                           | 参数类型                                     | 描述                                       |
18| ---------------------------- | ---------------------------------------- | ---------------------------------------- |
19| bindMenu                     | content: Array<[MenuItem](#menuitem)&gt;&nbsp;\|&nbsp;[CustomBuilder](ts-types.md#custombuilder8),<br>options?: [MenuOptions](#menuoptions10) | 给组件绑定菜单,点击后弹出菜单。弹出菜单项支持图标+文本排列和自定义两种功能。<br/>content: 配置菜单项图标和文本的数组,或者自定义组件。<br/>options: 配置弹出菜单的参数。 |
20| bindContextMenu<sup>8+</sup> | content:&nbsp;[CustomBuilder](ts-types.md#custombuilder8),<br>responseType:&nbsp;[ResponseType](ts-appendix-enums.md#responsetype8)<br>options?: [ContextMenuOptions](#contextmenuoptions10) | 给组件绑定菜单,触发方式为长按或者右键点击,弹出菜单项需要自定义。<br/>responseType: 菜单弹出条件,长按或者右键点击。<br/>options: 配置弹出菜单的参数。 |
21
22## MenuItem
23
24| 名称               | 类型                                   | 必填 | 描述                   |
25| ------------------ | -------------------------------------- | ---- | ---------------------- |
26| value              | [ResourceStr](ts-types.md#resourcestr) | 是   | 菜单项文本。           |
27| icon<sup>10+</sup> | [ResourceStr](ts-types.md#resourcestr) | 否   | 菜单项图标。           |
28| action             | ()&nbsp;=&gt;&nbsp;void                | 是   | 点击菜单项的事件回调。 |
29
30## MenuOptions<sup>10+</sup>
31
32继承自[ContextMenuOptions](#contextmenuoptions10)。
33
34| 名称  | 类型   | 必填 | 描述                                                         |
35| ----- | ------ | ---- | ------------------------------------------------------------ |
36| title | string | 否   | 菜单标题。<br>**说明:** <br/>仅在content设置为Array<[MenuItem](#menuitem)&gt; 时生效。 |
37
38## ContextMenuOptions<sup>10+</sup>
39
40| 名称        | 类型                                         | 必填 | 描述                                                         |
41| ----------- | -------------------------------------------- | ---- | ------------------------------------------------------------ |
42| offset      | [Position](ts-types.md#position8)            | 否   | 菜单弹出位置的偏移量,不会导致菜单显示超出屏幕范围。<br/>**说明:**<br />菜单类型为相对⽗组件区域弹出时,⾃动根据菜单位置属性 (placement)将区域的宽或⾼计⼊偏移量中。<br/>当菜单相对父组件出现在上侧时(placement设置为Placement.TopLeftPlacement.TopPlacement.TopRight),x为正值,菜单相对组件向右进行偏移,y为正值,菜单相对组件向上进行偏移。<br/>当菜单相对父组件出现在下侧时(placement设置为Placement.BottomLeftPlacement.BottomPlacement.BottomRight),x为正值,菜单相对组件向右进行偏移,y为正值,菜单相对组件向下进行偏移。<br/>当菜单相对父组件出现在左侧时(placement设置为Placement.LeftTopPlacement.LeftPlacement.LeftBottom),x为正值,菜单相对组件向左进行偏移,y为正值,菜单相对组件向下进行偏移。<br/>当菜单相对父组件出现在右侧时(placement设置为Placement.RightTopPlacement.RightPlacement.RightBottom),x为正值,菜单相对组件向右进行偏移,y为正值,菜单相对组件向下进行偏移。<br/>如果菜单调整了显示位置(与placement初始值主方向不⼀致),则偏移值 (offset) 失效。 |
43| placement   | [Placement](ts-appendix-enums.md#placement8) | 否   | 菜单组件优先显示的位置,当前位置显示不下时,会自动调整位置。<br/>**说明:**<br />placement值设置为undefined、null或没有设置此选项时,按未设置placement处理,菜单跟随点击位置弹出。 |
44| enableArrow | boolean                                      | 否   | 是否显示箭头。如果菜单的大小和位置不足以放置箭头时,不会显示箭头。 <br/>默认值:false, 不显示箭头。<br/>**说明:**<br />enableArrow为true时,placement未设置或者值为非法值,默认在目标物上方显示,否则按照placement的位置优先显示。当前位置显示不下时,会自动调整位置,enableArrow为undefined时,不显示箭头。 |
45| arrowOffset | [Length](ts-types.md#length)                 | 否   | 箭头在菜单处的偏移。箭头在菜单水平方向时,偏移量为箭头至最左侧的距离,默认居中。箭头在菜单竖直方向时,偏移量为箭头至最上侧的距离,默认居中。偏移量必须合法且转换为具体数值时大于0才会生效,另外该值生效时不会导致箭头超出菜单四周的安全距离。根据配置的placement来计算是在水平还是竖直方向上偏移。 |
46| onAppear    | ()&nbsp;=&gt;&nbsp;void                      | 否   | 菜单弹出时的事件回调。                                       |
47| onDisappear | ()&nbsp;=&gt;&nbsp;void                      | 否   | 菜单消失时的事件回调。                                       |
48
49## 示例
50
51### 示例1
52
53普通菜单
54
55```ts
56// xxx.ets
57@Entry
58@Component
59struct MenuExample {
60  build() {
61    Column() {
62      Text('click for Menu')
63    }
64    .width('100%')
65    .margin({ top: 5 })
66    .bindMenu([
67      {
68        value: 'Menu1',
69        action: () => {
70          console.info('handle Menu1 select')
71        }
72      },
73      {
74        value: 'Menu2',
75        action: () => {
76          console.info('handle Menu2 select')
77        }
78      },
79    ])
80  }
81}
82```
83
84![zh-cn_image_0000001174582862](figures/zh-cn_image_0000001174582862.gif)
85
86### 示例2
87
88自定义内容菜单
89
90```ts
91@Entry
92@Component
93struct MenuExample {
94  @State listData: number[] = [0, 0, 0]
95
96  @Builder MenuBuilder() {
97    Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
98      ForEach(this.listData, (item:number, index) => {
99        Column() {
100          Row() {
101            Image($r("app.media.icon")).width(20).height(20).margin({ right: 5 })
102            Text(`Menu${index as number + 1}`).fontSize(20)
103          }
104          .width('100%')
105          .height(30)
106          .justifyContent(FlexAlign.Center)
107          .align(Alignment.Center)
108          .onClick(() => {
109            console.info(`Menu${index as number + 1} Clicked!`)
110          })
111
112          if (index != this.listData.length - 1) {
113            Divider().height(10).width('80%').color('#ccc')
114          }
115        }.padding(5).height(40)
116      })
117    }.width(100)
118  }
119
120  build() {
121    Column() {
122      Text('click for menu')
123        .fontSize(20)
124        .margin({ top: 20 })
125        .bindMenu(this.MenuBuilder)
126    }
127    .height('100%')
128    .width('100%')
129    .backgroundColor('#f0f0f0')
130  }
131}
132```
133
134![zh-cn_image_0000001186807708](figures/zh-cn_image_0000001186807708.gif)
135
136### 示例3
137
138菜单(长按触发显示)
139
140```ts
141// xxx.ets
142@Entry
143@Component
144struct ContextMenuExample {
145  @Builder MenuBuilder() {
146    Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
147      Text('Test menu item 1')
148        .fontSize(20)
149        .width(100)
150        .height(50)
151        .textAlign(TextAlign.Center)
152      Divider().height(10)
153      Text('Test menu item 2')
154        .fontSize(20)
155        .width(100)
156        .height(50)
157        .textAlign(TextAlign.Center)
158    }.width(100)
159  }
160
161  build() {
162    Column() {
163      Text('LongPress for menu')
164    }
165    .width('100%')
166    .margin({ top: 5 })
167    .bindContextMenu(this.MenuBuilder, ResponseType.LongPress)
168  }
169}
170```
171
172![longMenu](figures/longMenu.gif)
173
174### 示例4
175
176指向性菜单(右键触发显示)
177
178```ts
179// xxx.ets
180@Entry
181@Component
182struct DirectiveMenuExample {
183  @Builder MenuBuilder() {
184    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
185      Text('Options')
186      Divider().strokeWidth(2).margin(5).color('#F0F0F0')
187      Text('Hide')
188      Divider().strokeWidth(2).margin(5).color('#F0F0F0')
189      Text('Exit')
190    }
191    .width(200)
192  }
193
194  build() {
195    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
196      Column() {
197        Text("DirectiveMenuExample")
198          .fontSize(20)
199          .width('100%')
200          .height("25%")
201          .backgroundColor('#F0F0F0')
202          .textAlign(TextAlign.Center)
203          .bindContextMenu(this.MenuBuilder, ResponseType.RightClick, {
204            enableArrow: true,
205            placement: Placement.Bottom
206          })
207      }
208    }
209    .width('100%')
210    .height('100%')
211  }
212}
213```
214
215![zh-cn_image_0000001689126950](figures/zh-cn_image_0000001689126950.png)
216