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 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 187 188 189