SukiUI Toast 通知系统完全指南:Host 接入、流畅构建器与复杂交互实战

发布时间:2026/10/5 6:44:04
SukiUI Toast 通知系统完全指南:Host 接入、流畅构建器与复杂交互实战 UI组件桌面应用【免费下载链接】SukiUIUI Theme for AvaloniaUI项目地址https://gitcode.com/gh_mirrors/su/SukiUI点击查看免费下载SukiUIAvaloniaUI 的 UI 主题框架内置了一套完整的 Toast 通知体系以SukiToastHost作为应用任意层级的通知宿主以ISukiToastManager作为队列与生命周期中枢并通过FluentSukiToastBuilder提供链式 API 快速构造通知。本篇以官方文档 toast.md 为主线结合仓库源码深入讲解从 MVVM 接入、Toast 显示/关闭、交互回调到 Loading 与Update式复杂通知的完整实战方案读完后你将能够在自己的 SukiUI 应用中独立接入并定制任意粒度的 Toast 通知。SukiToastHost把通知宿主挂到窗口上SukiUI 通过SukiWindow.Hosts属性提供一种永远渲染在最上层包括标题栏之上的宿主机制除了 SukiDialogHost 之外默认就内置了 Toast 专用的 SukiToastHost。关于 Hosts 的整体说明可参考 hosts 文档其中有一条重要提示suki:SukiWindow.Hosts只在SukiWindow中有效切勿声明在普通页面View里否则不会生效。官方推荐的标准做法是把它放进SukiWindow.Hosts这样能获得最佳展示体验但 Toast 宿主也可以按需本地化到应用内的任意上下文。宿主的设计是 MVVM 友好的——只要你能拿到某个SukiToastHost所使用的ISukiToastManager实例就可以在该宿主中展示 Toast。MVVM 方式推荐!-- XMLNS definitions omitted for brevity -- suki:SukiWindow suki:SukiWindow.Hosts suki:SukiToastHost Manager{Binding ToastManager}/ /suki:SukiWindow.Hosts /suki:SukiWindowpublic class ExampleViewModel { public ISukiToastManager ToastManager { get; } new(); }这里Manager是 SukiToastHost 上注册的StyledPropertyISukiToastManager。宿主持有该属性后会在挂载到逻辑树时OnAttachedToLogicalTree订阅 Manager 的OnToastQueued/OnToastDismissed/OnAllToastsDismissed三个事件从而把 Manager 的队列状态实时映射为界面上的 Toast 卡片。Demo 主窗口 SukiUIDemoView.axaml 正是这样同时声明了 Toast 与 Dialog 两个宿主suki:SukiWindow.Hosts suki:SukiToastHost Manager{Binding ToastManager} / suki:SukiDialogHost Manager{Binding DialogManager} / /suki:SukiWindow.Hosts非 MVVM 方式Code-Behind如果不希望引入 MVVM也可以采用开箱即用的简单做法在 XAML 里给宿主一个Name然后在 Code-Behind 中把 Manager 赋给它。!-- XMLNS definitions omitted for brevity -- suki:SukiWindow suki:SukiWindow.Hosts suki:SukiToastHost NameToastManager/ /suki:SukiWindow.Hosts /suki:SukiWindowpublic class MainWindow : SukiWindow { public static ISukiToastManager ToastManager new SukiToastManager(); public MainWindow() { InitializeComponent(); ToastHost.Manager ToastManager; } }之后即可随时随地通过静态字段展示通知MainWindow.ToastManager.CreateToast() .Queue();注意示例中 XAML 的NameToastManager会生成名为ToastManager的字段而构造函数里赋值的对象是ToastHost.ManagerToastHost 是该宿主控件的字段名两者通过Manager属性建立关联。Demo 中的 ToastWindowDemo.axaml 与 ToastWindowDemo.axaml.cs 采用的正是这种 Code-Behind 赋 Manager 的模式。容量与位置MaxToasts 与 PositionSukiToastHost提供两个关键可配置属性见 SukiToastHost.csMaxToastsbyte默认5限制单个宿主同时展示的 Toast 数量。当队列中的 Toast 超过该值时宿主在ManagerOnToastQueued中会调用Manager.EnsureMaximum(MaxToasts)自动关闭最旧的 Toast 腾出空间源码实现见 SukiToastManager.EnsureMaximum。若设为 0则宿主直接忽略新入队的 Toast见 SukiToastHost.cs。PositionToastLocation默认BottomRight控制 Toast 堆叠在窗口的哪个角落。可选值定义在 ToastLocation.csBottomRight、BottomLeft、TopRight、TopLeft。宿主会据此设置自身的HorizontalAlignment/VerticalAlignment见 SukiToastHost.cs。ISukiToastManagerToast 队列与生命周期中枢ISukiToastManager接口定义是 Toast 系统的核心抽象宿主持有它业务代码也通过它来入队和关闭 Toast。接口提供的能力如下成员说明event OnToastQueued每当一个 Toast 入队时触发携带SukiToastQueuedEventArgsevent OnToastDismissed每当一个 Toast 被关闭时触发携带SukiToastDismissedEventArgs内含Toast与DismissSourceevent OnAllToastsDismissed一次性关闭全部 Toast 时触发Queue(ISukiToast)将 Toast 加入队列等待展示Dismiss(toast)/Dismiss(index)按对象或按索引关闭指定 ToastDismissRange(startIndex, count)关闭一段范围内的 ToastEnsureMaximum(maxAllowed)保证队列不超过最大值超出的部分按最旧优先关闭DismissAll()立即清空全部 ToastIsDismissed(toast)判断某个 Toast 是否已被关闭SetDismissTimerPollingInterval(...)调整关闭计时器的轮询间隔毫秒或TimeSpan默认实现 SukiToastManager 内部维护一个ListISukiToast队列并用一个DispatcherTimer默认50ms轮询一次驱动按时间自动关闭的逻辑在DismissPollingTimerOnTick中计算每个 Toast 的剩余存活时间超时则以SukiToastDismissSource.Timeout关闭未超时则持续更新DismissProgressValue0~1供界面上的倒计时进度条使用见 SukiToastManager.cs。值得注意的实现细节是源码注释明确强调事件必须在将 Toast 移出 Manager 之前触发以保证动画只播放一次——这解释了Dismiss方法中先触发OnToastDismissed与toast.OnDismissed、再执行RemoveAt的顺序。关闭 Toast 的来源由枚举 SukiToastDismissSource.cs 描述Code代码关闭、Click点击关闭、ActionButton点击操作按钮关闭、Timeout超时关闭。用流畅构建器构造并显示 ToastSukiUI 为 Toast 提供了流畅式Fluent构建器全部扩展方法定义在 FluentSukiToastBuilder.cs 中。推荐的起点是调用ISukiToastManager上的扩展方法CreateToast()它会返回一个SukiToastBuilder见 FluentSukiToastBuilder.cspublic static SukiToastBuilder CreateToast(this ISukiToastManager manager) new(manager);之后可以任意链式调用以下方法大部分方法都有配套的 XMLDoc 说明方法作用备注WithTitle(string)设置标题WithContent(object?)设置正文内容可以传入 ViewModelSukiUI 会通过默认的 View 定位策略自动找到对应 View见 FluentSukiToastBuilder.cs也可以直接传入控件例如ProgressBarOfType(NotificationType)设置通知类型决定图标与颜色默认InformationWithLoadingState(bool)切换为 Loading 状态Dismiss().After(...)/Dismiss().ByClicking()配置关闭机制见下一节OnClicked(...)/OnDismissed(...)注册交互回调WithActionButton(...)添加操作按钮可添加任意数量最后调用.Queue()将 Toast 立即入队展示SukiToastBuilder.Queue 内部调用Manager.Queue(Toast)并返回ISukiToast实例——返回实例是为了方便后续手动关闭它例如复杂交互示例中的toastManager.Dismiss(toast)。继续沿用上文 ViewModel 的简单示例public void DisplayToast() { ToastManager.CreateToast() .WithTitle(Example Toast) .WithContent(The content of an example toast can be seen here.) .Queue(); }此外还有一个便捷入口CreateSimpleInfoToast()见 FluentSukiToastBuilder.cs它直接返回一个信息类型、3 秒后自动关闭、可点击关闭的 Toast 构建器适合不需要定制关闭逻辑的快捷场景。Demo 中 ToastsViewModel.cs 的ShowInfoToast与ShowThreeInfoToasts连发三条都用到了它。关闭机制默认不关闭显式开启默认情况下Toast没有任何关闭机制——除非宿主容量MaxToasts被超出此时最旧的 Toast 会被挤掉。要让 Toast 可被关闭必须使用.Dismiss()方法开启关闭语句随后跟随具体的关闭方式一个 Toast 可以同时配置多种关闭方式。public void DisplayToast() { ToastManager.CreateToast() .Dismiss().After(TimeSpan.FromSeconds(3)) .Dismiss().ByClicking() .Queue(); }上面的例子创建了一个空 Toast3 秒后自动关闭或者被点击时立即关闭。关闭方式的底层实现.Dismiss().After(TimeSpan)调用SetDismissAfter(delay, interruptWhileHover true)见 SukiToastBuilder.cs。当delay.TotalMilliseconds 0时置CanDismissByTime true并设置DismissTimeout第二个参数interruptWhileHover默认为true表示鼠标悬停在 Toast 上时暂停倒计时——这在 SukiToast.axaml.cs 的OnPointerEntered/OnPointerExited中实现进入时把DismissStartTimestamp清零、进度重置为 1移出后重新计时。.Dismiss().ByClicking()置CanDismissByClicking true。当用户点击 Toast 卡片时ToastCardClickedHandler会先触发OnClicked回调再以SukiToastDismissSource.Click关闭见 SukiToast.axaml.cs。视觉反馈当CanDismissByTime为真时Toast 顶部会显示一条倒计时进度条PART_DismissProgressBar其Value双向绑定到DismissProgressValue见 SukiToast.axaml。交互点击回调、关闭回调与操作按钮SukiUI 提供一对基础回调用于用户交互.OnClicked()与.OnDismissed()。在此基础上.WithActionButton()可以创建更复杂的交互。public void DisplayToast() { ToastManager.CreateToast() .Dismiss().After(TimeSpan.FromSeconds(3)) .OnClicked(_ Console.WriteLine(Toast Clicked!)) .OnDismissed(_ Console.WriteLine(Toast Was Dismissed!)) .WithActionButton(Dismiss, _ { }, true) .Queue(); }这段代码演示了Toast 3 秒后自动关闭Toast 主体可以被点击任意次数每次触发OnClicked而操作按钮一旦被点击会立即关闭整个 Toast第三个参数dismissOnClick: true同时触发OnDismissed。各回调的语义见 FluentSukiToastBuilder.cs.OnClicked(ActionISukiToast)点击 Toast 卡片主体非按钮区域时调用。.OnDismissed(ActionISukiToast, SukiToastDismissSource)无论因何种原因超时、点击、按钮、代码被关闭时都会调用参数中携带关闭来源可用于区分路径。.WithActionButton(object buttonContent, ActionISukiToast onClicked, bool dismissOnClick false, SukiButtonStyles style SukiButtonStyles.Flat)添加一个操作按钮。buttonContent可以是文本也可以是任意控件如 ToastsViewModel.cs 中直接传入MaterialIcon图标dismissOnClick控制点击按钮后是否同时关闭 Toaststyle参数控制按钮外观取值来自 SukiButtonStyles.csBasic、Flat、Accent、Icon、Danger等支持|组合。按钮点击时先执行回调再按dismissOnClick决定是否以SukiToastDismissSource.ActionButton关闭见 SukiToast.axaml.cs。注意AddActionButton的旧重载bool flatStyle已被标记[Obsolete]建议直接使用新重载并传SukiButtonStyles见 SukiToastBuilder.cs。按钮在 Toast 模板中通过ItemsControl横向排列在底部区域见 SukiToast.axaml点击事件由SukiToast在加载时统一挂接。Toast 类型四种 NotificationType调用.OfType(NotificationType.xxx)可以一键切换 Toast 的类型外观。默认类型是Information。NotificationType来自 Avalonia 的Avalonia.Controls.Notifications命名空间SukiUI 在 SukiToastBuilder.SetType 中为每种类型映射了图标与前景色类型图标Icons前景色NotificationColor代码InformationInformationOutlineInfoIconForegroundNotificationType.InformationSuccessCheckSuccessIconForegroundNotificationType.SuccessWarningAlertOutlineWarningIconForegroundNotificationType.WarningErrorAlertOutlineErrorIconForegroundNotificationType.Error图标会显示在 Toast 卡片左侧的圆形徽章中前景色决定徽章的底色颜色资源定义在 NotificationColor.cs图标定义在 Icons.cs。四种类型的用法完全一致// Information ToastManager.CreateToast() .OfType(NotificationType.Information) .Queue(); // Success ToastManager.CreateToast() .OfType(NotificationType.Success) .Queue(); // Warning ToastManager.CreateToast() .OfType(NotificationType.Warning) .Queue(); // Error ToastManager.CreateToast() .OfType(NotificationType.Error) .Queue();Demo 中 ToastsViewModel.cs 的ShowTypeDemoToast给出了更完整的组合示例——同时设置了标题、正文、类型、3 秒自动关闭与点击关闭。Loading Toast显示加载状态通过.WithLoadingState(true)可以把 Toast 切换到 Loading 状态左侧的图标徽章会替换为一个波浪进度动画WaveProgress见 SukiToast.axamlpublic void DisplayToast() { ToastManager.CreateToast() .WithLoadingState(true) .Queue(); }实践建议Loading Toast 通常配合.Dismiss().After(...)使用否则它会一直停留在界面上直到被手动关闭。Demo 中的 ShowLoadingToast 就同时设置了 Loading 状态、3 秒自动关闭和点击关闭。复杂交互实战一个完整的Update通知文档最后给出了一个极具代表性的场景——版本更新通知先展示一个带两个操作按钮的提示点击Update后切换为带进度条的更新中 Toast进度走完后自动关闭。下面两段代码直接取自 Demo 的 ToastsViewModel.cs与文档示例等价private void ShowActionToast() { toastManager.CreateToast() .WithTitle(Update Available) .WithContent(Information, Update v1.0.0.0 is Now Available.) .WithActionButtonNormal(Later, _ { }, true) .WithActionButton(Update, _ ShowUpdatingToast(), true) .Queue(); } private void ShowUpdatingToast() { var progress new ProgressBar() { Value 0, ShowProgressText true }; var toast toastManager.CreateToast() .WithTitle(Updating...) .WithContent(progress) .Queue(); var timer new Timer(20); timer.Elapsed (_, _) { Dispatcher.UIThread.Invoke(() { progress.Value 1; if (progress.Value 100) return; timer.Dispose(); toastManager.Dismiss(toast); }); }; timer.Start(); }这个例子的技术要点WithActionButtonNormal/WithActionButton分别以Basic和Flat两种按钮风格添加Later与Update按钮dismissOnClick: true使点击任一会关闭当前 Toast。Demo 中还展示了自定义按钮样式SukiButtonStyles.Flat | SukiButtonStyles.Accent | SukiButtonStyles.Icon与图标按钮的写法见 ToastsViewModel.cs。控件作为内容WithContent(progress)直接把一个ProgressBar控件当作 Toast 正文展示任意 UI 的能力。手动关闭Queue()返回的toast实例被保存下来进度完成后调用toastManager.Dismiss(toast)以代码方式关闭对应SukiToastDismissSource.Code。UI 线程调度定时器的回调通过Dispatcher.UIThread.Invoke切回 UI 线程更新进度条避免跨线程访问控件。进阶实践依赖注入、多窗口与动画机制通过 DI 注册单例 Manager在大型应用中建议把ISukiToastManager注册为单例并由 DI 容器分发。Demo 的做法见 App.axaml.csservices.AddSingletonISukiToastManager, SukiToastManager(); services.AddSingletonISukiDialogManager, SukiDialogManager();各页面 ViewModel 通过构造函数注入ISukiToastManager如 ToastsViewModel.cs这样任何页面都能向同一个宿主投递通知。多窗口为每个窗口指定独立宿主Toast 系统支持每个窗口各自管理或多窗口共享。Demo 的 ToastWindowDemo.axaml.cs 演示了三种情况为弹出窗口新建独立的SukiToastManager并赋给该窗口的ToastHost.Manager也可以把主窗口的 Manager 传入弹出窗口让弹出窗口往主窗口投递 Toast注释中还提到可以轻松共享同一个ISukiToastManager实例来实现多窗口统一通知。动画与对象池Toast 背后的实现细节从源码结构看Toast 的展示/关闭动画由 SukiToastMotion.cs 驱动入队时卡片以弹性弹簧critically damped spring从右下角滑入并放大、模糊渐入关闭时向右滑出、淡出并折叠高度动画参数时长、位移、模糊半径、弹簧频率集中配置在 SukiToastProfile.cs提供 Normal 与 Lite 两套预设SukiAnimationTheme可在运行时切换切换只影响下一次展示的 Toast。另外ToastPool.cs 维护了一个ConcurrentBagISukiToast对象池Toast 关闭动画结束后被归还池中下次创建时通过ResetToDefault()复用避免频繁创建/销毁控件带来的 GC 压力——这也是SukiToastBuilder构造时调用ToastPool.Get()见 SukiToastBuilder.cs的原因。小结SukiUI 的 Toast 体系可以概括为三条主线宿主层SukiToastHost声明在SukiWindow.Hosts通过Manager绑定 MaxToasts/Position控制容量与位置、管理层ISukiToastManager负责入队、关闭、批量清空与超时轮询、构建层FluentSukiToastBuilder的链式 API 组合标题、内容、类型、关闭方式、回调与操作按钮。无论是简单的信息提示、带自动关闭与点击关闭的轻提示还是带进度条的复杂Update通知都可以用同一套 API 在几行代码内完成。想要深入理解每个环节可以从 FluentSukiToastBuilder.cs、SukiToastManager.cs、SukiToastHost.cs 与 SukiToast.axaml.cs 这几个核心文件开始结合 ToastsView.axaml 及其 ViewModel 查看全部演示用例。赞分享UI组件桌面应用【免费下载链接】SukiUIUI Theme for AvaloniaUI项目地址https://gitcode.com/gh_mirrors/su/SukiUI点击查看免费下载相关推荐ng-zorro-antd Notification 通知模板渲染实战用 NzNotificationService.template 构建复杂交互通知ng zorro antd Notification 通知模板渲染实战用 NzNotificationService.template 构建复杂交互通知 在UI组件前端AhMyth持久化技术确保Android RAT在设备重启后继续运行的完整指南AhMyth持久化技术确保Android RAT在设备重启后继续运行的完整指南 AhMyth是一款强大的跨平台Android远程管理工具其持久化技术是确保R网络安全渗透测试ACRA通知系统完整教程Toast、Dialog、Notification交互详解ACRA通知系统完整教程Toast、Dialog、Notification交互详解 Android应用崩溃报告系统ACRA提供了多种用户交互方式帮助开发者在移动开发异常检测上一篇终极缠论分析工具ChanlunX通达信插件完整使用指南下一篇轻量级浏览器Midori如何在资源有限的环境中实现高效网页浏览创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考