1# 气泡提示(Popup)
2Popup属性可绑定在组件上显示气泡弹窗提示,设置弹窗内容、交互逻辑和显示状态。主要用于屏幕录制、信息弹出提醒等显示状态。
3
4气泡分为两种类型,一种是系统提供的气泡[PopupOptions](../reference/apis-arkui/arkui-ts/ts-universal-attributes-popup.md#popupoptions类型说明),一种是开发者可以自定义的气泡[CustomPopupOptions](../reference/apis-arkui/arkui-ts/ts-universal-attributes-popup.md#custompopupoptions8类型说明)。其中,PopupOptions通过配置primaryButton和secondaryButton来设置带按钮的气泡,CustomPopupOptions通过配置[builder](../../application-dev/quick-start/arkts-builder.md)来设置自定义的气泡。
5
6气泡可以通过配置[mask](../reference/apis-arkui/arkui-ts/ts-universal-attributes-popup.md#popupoptions类型说明)来实现模态和非模态窗口,mask为true或者颜色值的时候,气泡为模态窗口,mask为false时,气泡为非模态窗口。
7
8## 文本提示气泡
9
10文本提示气泡常用于只展示带有文本的信息提示,不带有任何交互的场景。Popup属性需绑定组件,当bindPopup属性中参数show为true时会弹出气泡提示。
11
12在Button组件上绑定Popup属性,每次点击Button按钮,handlePopup会切换布尔值,当值为true时,触发bindPopup弹出气泡。
13
14```ts
15@Entry
16@Component
17struct PopupExample {
18  @State handlePopup: boolean = false
19
20  build() {
21    Column() {
22      Button('PopupOptions')
23        .onClick(() => {
24          this.handlePopup = !this.handlePopup
25        })
26        .bindPopup(this.handlePopup, {
27          message: 'This is a popup with PopupOptions',
28        })
29    }.width('100%').padding({ top: 5 })
30  }
31}
32```
33
34![zh-cn_image_0000001511740524](figures/zh-cn_image_0000001511740524.png)
35
36## 添加气泡状态变化的事件
37
38通过onStateChange参数为气泡添加状态变化的事件回调,可以判断当前气泡的显示状态。
39
40```ts
41@Entry
42@Component
43struct PopupExample {
44  @State handlePopup: boolean = false
45
46  build() {
47    Column() {
48      Button('PopupOptions')
49        .onClick(() => {
50          this.handlePopup = !this.handlePopup
51        })
52        .bindPopup(this.handlePopup, {
53          message: 'This is a popup with PopupOptions',
54          onStateChange: (e)=> { // 返回当前的气泡状态
55            if (!e.isVisible) {
56              this.handlePopup = false
57            }
58          }
59        })
60    }.width('100%').padding({ top: 5 })
61  }
62}
63```
64
65![PopupOnStateChange](figures/PopupOnStateChange.gif)
66
67## 带按钮的提示气泡
68
69通过primaryButton、secondaryButton属性为气泡最多设置两个Button按钮,通过此按钮进行简单的交互,开发者可以通过配置action参数来设置想要触发的操作。
70
71```ts
72@Entry
73@Component
74struct PopupExample22 {
75  @State handlePopup: boolean = false
76
77  build() {
78    Column() {
79      Button('PopupOptions').margin({ top: 200 })
80        .onClick(() => {
81          this.handlePopup = !this.handlePopup
82        })
83        .bindPopup(this.handlePopup, {
84          message: 'This is a popup with PopupOptions',
85          primaryButton: {
86            value: 'Confirm',
87            action: () => {
88              this.handlePopup = !this.handlePopup
89              console.info('confirm Button click')
90            }
91          },
92          secondaryButton: {
93            value: 'Cancel',
94            action: () => {
95              this.handlePopup = !this.handlePopup
96            }
97          },
98          onStateChange: (e) => {
99            if (!e.isVisible) {
100              this.handlePopup = false
101            }
102          }
103        })
104    }.width('100%').padding({ top: 5 })
105  }
106}
107```
108
109![zh-cn_other_0000001500740342](figures/zh-cn_other_0000001500740342.jpeg)
110
111## 气泡的动画
112
113气泡通过定义transition控制气泡的进场和出场动画效果。
114
115```ts
116// xxx.ets
117@Entry
118@Component
119struct PopupExample {
120  @State handlePopup: boolean = false
121  @State customPopup: boolean = false
122
123  // popup构造器定义弹框内容
124  @Builder popupBuilder() {
125    Row() {
126      Text('Custom Popup with transitionEffect').fontSize(10)
127    }.height(50).padding(5)
128  }
129
130  build() {
131    Flex({ direction: FlexDirection.Column }) {
132      // PopupOptions 类型设置弹框内容
133      Button('PopupOptions')
134        .onClick(() => {
135          this.handlePopup = !this.handlePopup
136        })
137        .bindPopup(this.handlePopup, {
138          message: 'This is a popup with transitionEffect',
139          placementOnTop: true,
140          showInSubWindow: false,
141          onStateChange: (e) => {
142            if (!e.isVisible) {
143              this.handlePopup = false
144            }
145          },
146          // 设置弹窗显示动效为透明度动效与平移动效的组合效果,无退出动效
147          transition:TransitionEffect.asymmetric(
148            TransitionEffect.OPACITY.animation({ duration: 1000, curve: Curve.Ease }).combine(
149              TransitionEffect.translate({ x: 50, y: 50 })),
150            TransitionEffect.IDENTITY)
151        })
152        .position({ x: 100, y: 150 })
153
154      // CustomPopupOptions 类型设置弹框内容
155      Button('CustomPopupOptions')
156        .onClick(() => {
157          this.customPopup = !this.customPopup
158        })
159        .bindPopup(this.customPopup, {
160          builder: this.popupBuilder,
161          placement: Placement.Top,
162          showInSubWindow: false,
163          onStateChange: (e) => {
164            if (!e.isVisible) {
165              this.customPopup = false
166            }
167          },
168          // 设置弹窗显示动效与退出动效为缩放动效
169          transition:TransitionEffect.scale({ x: 1, y: 0 }).animation({ duration: 500, curve: Curve.Ease })
170        })
171        .position({ x: 80, y: 300 })
172    }.width('100%').padding({ top: 5 })
173  }
174}
175```
176
177![popup_transition](figures/popup_transition.gif)
178
179## 自定义气泡
180
181开发者可以使用CustomPopupOptions的builder创建自定义气泡,\@Builder中可以放自定义的内容。除此之外,还可以通过popupColor等参数控制气泡样式。
182
183```ts
184@Entry
185@Component
186struct Index {
187  @State customPopup: boolean = false
188  // popup构造器定义弹框内容
189  @Builder popupBuilder() {
190    Row({ space: 2 }) {
191      Image($r("app.media.icon")).width(24).height(24).margin({ left: 5 })
192      Text('This is Custom Popup').fontSize(15)
193    }.width(200).height(50).padding(5)
194  }
195  build() {
196    Column() {
197      Button('CustomPopupOptions')
198        .position({x:100,y:200})
199        .onClick(() => {
200          this.customPopup = !this.customPopup
201        })
202        .bindPopup(this.customPopup, {
203          builder: this.popupBuilder, // 气泡的内容
204          placement:Placement.Bottom, // 气泡的弹出位置
205          popupColor:Color.Pink, // 气泡的背景色
206          onStateChange: (e) => {
207            if (!e.isVisible) {
208              this.customPopup = false
209            }
210          }
211        })
212    }
213    .height('100%')
214  }
215}
216```
217
218使用者通过配置placement参数将弹出的气泡放到需要提示的位置。弹窗构造器会触发弹出提示信息,来引导使用者完成操作,也让使用者有更好的UI体验。
219
220![zh-cn_other_0000001500900234](figures/zh-cn_other_0000001500900234.jpeg)
221
222## 气泡样式
223
224气泡除了可以通过builder实现自定义气泡,还可以通过接口设置气泡的样式和显示效果。
225
226背景颜色:气泡的背景色默认为透明,但是会有一个默认的模糊效果,手机上为COMPONENT\_ULTRA\_THICK。
227蒙层样式:气泡默认有蒙层,且蒙层的颜色为透明。
228显示大小:气泡大小有内部的builder大小或者message的长度决定的。
229显示位置:气泡默认显示在宿主组件的下方,可以通过Placement接口来配置其显示位置以及对齐方向。
230以下示例通过设置popupColor(背景颜色)、mask(蒙层样式)、width(气泡宽度)、placement(显示位置)实现气泡的样式。
231
232```ts
233// xxx.ets
234
235@Entry
236@Component
237struct PopupExample {
238  @State handlePopup: boolean = false
239
240  build() {
241    Column({ space: 100 }) {
242      Button('PopupOptions')
243        .onClick(() => {
244          this.handlePopup = !this.handlePopup
245        })
246        .bindPopup(this.handlePopup, {
247          width: 200,
248          message: 'This is a popup.',
249          popupColor: Color.Red, // 设置气泡的背景色
250          mask: {
251            color: '#33d9d9d9'
252          },
253          placement: Placement.Top,
254          backgroundBlurStyle: BlurStyle.NONE // 去除背景模糊效果需要关闭气泡的模糊背景
255        })
256    }
257    .width('100%')
258  }
259}
260```
261
262![image](figures/UIpopupStyle.gif)
263
264
265