HarmonyOS的Toast接口,不支持设定圆角样式。如何实现类似其他平台的Toast样式?

如果需要实现类似其他平台的Toast样式,可借助自定义弹窗实现。
主要实现思路为,借助Text组件自定义类似其他平台Toast的UI样式,并封装为@Builder构建函数,将该函数传入ComponentContent创建弹窗对象,通过getUIContext开启该弹窗对象,开启后执行setTimeout,等待指定的时间后,执行关闭弹窗对象。详细步骤如下:
@Component struct ToastContent { public text: string = ''; public clickText: string = ''; public clickListener = () => { }; private textList: string[] = []; aboutToAppear(): void { if (this.clickText.length > 0) { this.textList = this.text.split(this.clickText); } } build() { Column() { if (this.clickText === '') { Text(this.text).toastText(); } else { Text() { ForEach(this.textList, (item: string, num: number) => { Span(item); if (num < this.textList.length - 1) { Span(this.clickText).fontColor(Color.Yellow); } }); }.onClick(this.clickListener).toastText(); } } .borderRadius(5) .backgroundColor(Color.Black) .padding(10) .justifyContent(FlexAlign.SpaceBetween) .margin({ left: '5%', right: '5%' }); } } // 封装Toast的@Builder方法 @Builder function buildText(params: Params) { ToastContent({ text: params.text, clickText: params.clickText, clickListener: params.clickListener }); } // 封装公共样式 @Extend(Text) function toastText() { .fontSize(20) .fontColor(Color.White); }
/** * 封装全局蓝色浮动提示,支持点击 */ export class Toast { private toastParams: Params; constructor(text: string, time: number = 2000) { this.toastParams = new Params(text, time); } setClick(clickText: string, clickListener: () => void): Toast { this.toastParams.setClick(clickText, clickListener); return this; }; async show() { let uiContext = AppStorage.get('currentUIContext') as UIContext; let click = this.toastParams.clickListener; let contentNode = new ComponentContent(uiContext, wrapBuilder(buildText), this.toastParams); uiContext.getPromptAction().openCustomDialog(contentNode, { showInSubWindow: this.toastParams.clickText === '' ? false : true, isModal: false, offset: { dx: 0, dy: '10%' } }).then(() => { setTimeout(() => { uiContext.getPromptAction().closeCustomDialog(contentNode); }, this.toastParams.time); }); this.toastParams.clickListener = () => { click(); uiContext.getPromptAction().closeCustomDialog(contentNode); }; }; }
new Toast('点击Toast后屏幕将退出横屏,进入到竖屏状态', 3000).setClick('关闭自动添加', () => { this.windowClass.setPreferredOrientation(window.Orientation.PORTRAIT); this.pathStack.pushPathByName('DetailPage', null); }).show();
完整示例参考如下:
import { common } from '@kit.AbilityKit'; import { Toast } from './ToastContent'; import { window } from '@kit.ArkUI'; @Entry @Component struct Index { pathStack: NavPathStack = new NavPathStack(); private context = this.getUIContext().getHostContext() as common.UIAbilityContext; private windowClass = (this.context as common.UIAbilityContext).windowStage.getMainWindowSync(); setOrientation(orientation: number) { this.windowClass.setPreferredOrientation(orientation).then(() => { }).catch(() => { }); } async aboutToAppear(): Promise<void> { await this.windowClass.setPreferredOrientation(window.Orientation.LANDSCAPE); AppStorage.setOrCreate('currentUIContext', this.getUIContext()); } build() { Navigation(this.pathStack) { RelativeContainer() { Column() { Text('我的记录') .fontSize(50) .width('100%') .textAlign(TextAlign.Center) .fontWeight(FontWeight.Bold) Button('保存') .onClick(() => { new Toast('点击Toast后屏幕将退出横屏,进入到竖屏状态', 3000).setClick('关闭自动添加', () => { this.windowClass.setPreferredOrientation(window.Orientation.PORTRAIT); this.pathStack.pushPathByName('DetailPage', null); }).show(); }) .backgroundColor(Color.Blue) .fontColor(Color.White) } .alignRules({ center: { anchor: '__container__', align: VerticalAlign.Center }, middle: { anchor: '__container__', align: HorizontalAlign.Center } }) } .width('100%') } .mode(NavigationMode.Stack) .height('100%') .width('100%') .height('100%') .hideTitleBar(true) } }
import { ComponentContent } from '@kit.ArkUI'; /** * 封装全局蓝色浮动提示,支持点击 */ export class Toast { private toastParams: Params; constructor(text: string, time: number = 2000) { this.toastParams = new Params(text, time); } setClick(clickText: string, clickListener: () => void): Toast { this.toastParams.setClick(clickText, clickListener); return this; }; async show() { let uiContext = AppStorage.get('currentUIContext') as UIContext; let click = this.toastParams.clickListener; let contentNode = new ComponentContent(uiContext, wrapBuilder(buildText), this.toastParams); uiContext.getPromptAction().openCustomDialog(contentNode, { showInSubWindow: this.toastParams.clickText === '' ? false : true, isModal: false, offset: { dx: 0, dy: '10%' } }).then(() => { setTimeout(() => { uiContext.getPromptAction().closeCustomDialog(contentNode); }, this.toastParams.time); }); this.toastParams.clickListener = () => { click(); uiContext.getPromptAction().closeCustomDialog(contentNode); }; }; } // 参数 class Params { text: string = ''; time: number = 2000; clickText: string = ''; clickListener = () => { }; constructor(text: string, time: number = 2000) { this.text = text; this.time = time; } setClick(clickText: string, clickListener: () => void) { this.clickText = clickText; this.clickListener = clickListener; }; } @Component struct ToastContent { public text: string = ''; public clickText: string = ''; public clickListener = () => { }; private textList: string[] = []; aboutToAppear(): void { if (this.clickText.length > 0) { this.textList = this.text.split(this.clickText); } } build() { Column() { if (this.clickText === '') { Text(this.text).toastText(); } else { Text() { ForEach(this.textList, (item: string, num: number) => { Span(item); if (num < this.textList.length - 1) { Span(this.clickText).fontColor(Color.Yellow); } }); }.onClick(this.clickListener).toastText(); } } .borderRadius(5) .backgroundColor(Color.Black) .padding(10) .justifyContent(FlexAlign.SpaceBetween) .margin({ left: '5%', right: '5%' }); } } // 封装Toast的@Builder方法 @Builder function buildText(params: Params) { ToastContent({ text: params.text, clickText: params.clickText, clickListener: params.clickListener }); } // 封装公共样式 @Extend(Text) function toastText() { .fontSize(20) .fontColor(Color.White); }
@Builder export function DetailPageBuilder() { DetailPage() } @Component export struct DetailPage { pageInfos: NavPathStack = new NavPathStack(); build() { NavDestination() { Column() { }.width('100%').height('100%') }.title('DetailPage') } }
该知识是综合了自定义弹窗和延时关闭功能,实现了自定义样式的Toast。可直接将上述show接口的实现代码,结合业务需要自定义Toast样式,并粘贴至自己的文件调用。