• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 即时反馈(Toast)
2<!--Kit: ArkUI-->
3<!--Subsystem: ArkUI-->
4<!--Owner: @liyi0309-->
5<!--Designer: @liyi0309-->
6<!--Tester: @lxl007-->
7<!--Adviser: @HelloCrease-->
8
9即时反馈(Toast)是一种临时性的消息提示框,用于向用户显示简短的操作反馈或状态信息。​它通常在屏幕的底部或顶部短暂弹出,随后在一段时间后自动消失。即时反馈的主要目的是提供简洁、不打扰的信息反馈,避免干扰用户当前的操作流程。
10
11
12可以通过使用[UIContext](../reference/apis-arkui/arkts-apis-uicontext-uicontext.md)中的[getPromptAction](../reference/apis-arkui/arkts-apis-uicontext-uicontext.md#getpromptaction)方法获取当前UI上下文关联的[PromptAction](../reference/apis-arkui/arkts-apis-uicontext-promptaction.md)对象,再通过该对象调用[showToast](../reference/apis-arkui/arkts-apis-uicontext-promptaction.md#showtoast)创建并显示文本提示框。
13
14> **说明:**
15>
16> 为了安全考虑,例如Toast恶意遮挡其他页面,Toast只能显示在当前的UI实例中,应用退出后,不会单独显示在桌面上。
17
18## 使用建议
19
20 - 合理使用弹出场景,避免过度提醒用户。
21
22    可以针对以下常用场景使用即时反馈操作,例如,当用户执行某个操作时及时结果反馈,用来提示用户操作是否成功或失败;或是当应用程序的状态发生变化时提供状态更新等。
23
24 - 注意文本的信息密度,即时反馈展示时间有限,应当避免长文本的出现。
25
26   Toast控件的文本应该清晰可读,字体大小和颜色应该与应用程序的主题相符。除此之外,即时反馈控件本身不应该包含任何可交互的元素,如按钮或链接。
27
28 - 杜绝强制占位和密集弹出的提示。
29
30   即时反馈作为应用内的轻量通知,应当避免内容布局占用界面内的其他元素信息,如遮盖弹出框的展示内容,从而迷惑用户弹出的内容是否属于弹出框。再或者频繁性的弹出信息内容,且每次弹出之间无时间间隔,影响用户的正常使用。也不要在短时间内频繁弹出新的即时反馈替代上一个。即时反馈的单次显示时长不要超过 3 秒钟,避免影响用户正常的行为操作。
31
32 - 遵从系统默认弹出位置。
33
34   即时反馈在系统中默认从界面底部弹出,距离底部有一定的安全间距,作为系统性的应用内提示反馈,请遵守系统默认效果,避免与其他弹出类组件内容重叠。特殊场景下可对内容布局进行规避。
35
36 - 弹框字体最大放大倍数限制。
37
38   即时反馈中,字体的最大放大倍数为2。
39
40## 即时反馈模式对比
41
42即时反馈提供了两种显示模式,分别为DEFAULT(显示在应用内)、TOP\_MOST(显示在应用之上)。
43
44在TOP_MOST类型的Toast显示前,会创建一个全屏大小的子窗(手机上子窗大小和主窗大小一致),然后在该子窗上计算Toast的布局位置,最后显示在该子窗上。具体和DEFAULT模式Toast的差异如下:
45
46| 差异点| DEFAULT | TOP_MOST |
47| --- | --- | --- |
48| 是否创建子窗	 | 否 | 是 |
49| 层级 | 显示在主窗内,层级和主窗一致,一般比较低 | 显示在子窗中,一般比主窗层级高,比其他弹窗类组件层级高,比软键盘和权限弹窗层级低 |
50| 是否避让软键盘 | 软键盘抬起时,必定上移软键盘的高度 | 软键盘抬起时,只有toast被遮挡时,才会避让,且避让后toast底部距离软键盘高度为80vp |
51| UIExtension内布局 | 以UIExtension为主窗中布局,对齐方式与UIExtension对齐 | 以宿主窗口为主窗中布局,对齐方式与宿主窗口对齐 |
52
53```ts
54import { promptAction } from '@kit.ArkUI';
55
56@Entry
57@Component
58struct Index {
59  build() {
60    Column({ space: 10 }) {
61      TextInput()
62      Button() {
63        Text("DEFAULT类型Toast")
64          .fontSize(20)
65          .fontWeight(FontWeight.Bold)
66
67      }
68      .width('100%')
69      .onClick(() => {
70        this.getUIContext().getPromptAction().showToast({
71          message: "ok,我是DEFAULT toast",
72          duration: 2000,
73          showMode: promptAction.ToastShowMode.DEFAULT,
74          bottom: 80
75        });
76      })
77
78      Button() {
79        Text("TOPMOST类型Toast")
80          .fontSize(20)
81          .fontWeight(FontWeight.Bold)
82
83      }
84      .width('100%')
85      .onClick(() => {
86        this.getUIContext().getPromptAction().showToast({
87          message: "ok,我是TOP_MOST toast",
88          duration: 2000,
89          showMode: promptAction.ToastShowMode.TOP_MOST,
90          bottom: 85
91        });
92      })
93    }
94  }
95}
96```
97
98## 创建即时反馈
99
100适用于短时间内提示框自动消失的场景。
101
102```ts
103import { PromptAction } from '@kit.ArkUI';
104import { BusinessError } from '@kit.BasicServicesKit';
105
106@Entry
107@Component
108struct toastExample {
109  private uiContext: UIContext = this.getUIContext();
110  private promptAction: PromptAction = this.uiContext.getPromptAction();
111
112  build() {
113    Column() {
114      Button('Show toast').fontSize(20)
115        .onClick(() => {
116          try {
117            this.promptAction.showToast({
118              message: 'Hello World',
119              duration: 2000
120            })
121          } catch (error) {
122            let message = (error as BusinessError).message;
123            let code = (error as BusinessError).code;
124            console.error(`showToast args error code is ${code}, message is ${message}`);
125          };
126        })
127    }.height('100%').width('100%').justifyContent(FlexAlign.Center)
128  }
129}
130```
131
132![image](figures/UIToast1.gif)
133
134## 显示关闭即时反馈
135
136适用于提示框停留时间较长,用户操作可以提前关闭提示框的场景。
137
138```ts
139import { LengthMetrics, PromptAction } from '@kit.ArkUI';
140import { BusinessError } from '@kit.BasicServicesKit';
141
142@Entry
143@Component
144struct toastExample {
145  @State toastId: number = 0;
146  private uiContext: UIContext = this.getUIContext();
147  private promptAction: PromptAction = this.uiContext.getPromptAction();
148
149  build() {
150    Column() {
151      Button('Open Toast')
152        .type(ButtonType.Capsule)
153        .height(100)
154        .onClick(() => {
155          try {
156            this.promptAction.openToast({
157              message: 'Toast Message',
158              duration: 10000,
159            }).then((toastId: number) => {
160              this.toastId = toastId;
161            });
162          } catch (error) {
163            let message = (error as BusinessError).message;
164            let code = (error as BusinessError).code;
165            console.error(`OpenToast error code is ${code}, message is ${message}`);
166          };
167        })
168      Blank().height(50);
169      Button('Close Toast')
170        .height(100)
171        .type(ButtonType.Capsule)
172        .onClick(() => {
173          try {
174            this.promptAction.closeToast(this.toastId);
175          } catch (error) {
176            let message = (error as BusinessError).message;
177            let code = (error as BusinessError).code;
178            console.error(`CloseToast error code is ${code}, message is ${message}`);
179          };
180        })
181    }.height('100%').width('100%').justifyContent(FlexAlign.Center)
182  }
183}
184```
185
186![image](figures/UIToast.gif)
187
188
189