[Flutter]自定义等待转圈和Toast提示

1.自定义样式

2.自定义LoadingView

import 'package:flutter/material.dart';enum LoadingStyle {onlyIndicator, // 仅一个转圈等待roundedRectangle, // 添加一个圆角矩形当背景maskingOperation, // 添加一个背景蒙层, 阻止用户操作
}class LoadingView {static final LoadingView _singleton = LoadingView._internal();factory LoadingView() {return _singleton;}LoadingView._internal();OverlayEntry? _overlayEntry;  void show(BuildContext context, {LoadingStyle type = LoadingStyle.onlyIndicator}) {if (_overlayEntry == null) {_overlayEntry = _createOverlayEntry(type);Overlay.of(context).insert(_overlayEntry!);  }}void hide() {_overlayEntry?.remove();_overlayEntry = null;}OverlayEntry _createOverlayEntry(LoadingStyle type) => OverlayEntry(builder: (BuildContext context) {List<Widget> stackChildren = [];if (type == LoadingStyle.roundedRectangle) {stackChildren.add(Center(child: Container(width: 100,height: 100,padding: const EdgeInsets.all(20.0),decoration: BoxDecoration(color: Colors.white,borderRadius: BorderRadius.circular(8.0),),child: const Align(alignment: Alignment.center,child: SizedBox(width: 45,height: 45,child: CircularProgressIndicator(color: Colors.black,),),),),),);} else if (type == LoadingStyle.maskingOperation) {stackChildren.addAll([const Opacity(opacity: 0.5,child: ModalBarrier(dismissible: false, color: Colors.black),),const Center(child: CircularProgressIndicator()),]);} else {stackChildren.add(const Center(child: CircularProgressIndicator()),);}return Stack(children: stackChildren);},);
}

3.自定义ToastView

import 'package:flutter/material.dart';enum ToastPosition { center, bottom }class ToastView {static OverlayEntry? _overlayEntry;static void showToast(BuildContext context,String message, {ToastPosition position = ToastPosition.center,int second = 2,Color backgroundColor = Colors.white,Color textColor = Colors.black,double horizontalMargin = 16,EdgeInsetsGeometry padding = const EdgeInsets.symmetric(horizontal: 16, vertical: 10),}) {_overlayEntry?.remove();_overlayEntry = OverlayEntry(builder: (context) => ToastWidget(message: message,position: position,backgroundColor: backgroundColor,textColor: textColor,horizontalMargin: horizontalMargin,padding: padding,),);Overlay.of(context)?.insert(_overlayEntry!);Future.delayed(Duration(seconds: second), () {_overlayEntry?.remove();_overlayEntry = null;});}
}class ToastWidget extends StatelessWidget {final String message;final ToastPosition position;final Color backgroundColor;final Color textColor;final double horizontalMargin;final EdgeInsetsGeometry padding;const ToastWidget({Key? key,required this.message,required this.position,required this.backgroundColor,required this.textColor,required this.horizontalMargin,required this.padding,}) : super(key: key);@overrideWidget build(BuildContext context) {return Positioned(top: position == ToastPosition.center ? MediaQuery.of(context).size.height / 2 : null,bottom: position == ToastPosition.bottom ? 50.0 : null,left: horizontalMargin,right: horizontalMargin,child: Material(color: Colors.transparent,child: Align(alignment: position == ToastPosition.center ? Alignment.center : Alignment.bottomCenter,child: FittedBox(fit: BoxFit.scaleDown,child: Container(padding: padding,decoration: BoxDecoration(color: backgroundColor,borderRadius: BorderRadius.circular(8),),child: Text(message,textAlign: TextAlign.center,style: TextStyle(fontSize: 15,color: textColor,),),),),),),);}
}

4.创建一个全局的回调管理AlertCallbackManager

经过上面自定义视图,我们注意到,视图的展示都需要BuildContext context。若是这样的话,就强行将弹窗视图的逻辑绑定到了具体的某个组件上,导致组件销毁时弹窗也必须销毁。否则,context都消失了,你又如何去处理插入其中的视图?

我们往往需要,让等待转圈在离开页面后还继续展示,让Toast在关闭页面时也不被影响到其提示的时长。

所以,这里我们用了一个全局回调管理。

enum AlertCallbackType { none, showLoading, hideLoading, showToast }class AlertCallbackManager {// 私有构造函数AlertCallbackManager._privateConstructor();// 单例实例static final AlertCallbackManager _instance = AlertCallbackManager._privateConstructor();// 获取单例实例的方法static AlertCallbackManager get instance => _instance;// 定义闭包类型的回调函数Function(AlertCallbackType type, String message)? callback;
}

5.创建一个根组件,将等待加载和Toast提示当作公共逻辑来处理。

有了全局回调管理,我们还需要有一个不会被轻易销毁的根组件,来提供BuildContext context。

注意:全局提示回调, 要放在MaterialApp包装之后,因为这里的LoadingView实现方式需要放在MaterialApp之下。

void main() async {WidgetsFlutterBinding.ensureInitialized();runApp(const MyApp());
}// MARK: 用来包装MaterialApp
class MyApp extends StatelessWidget {const MyApp({super.key});@overrideWidget build(BuildContext context) {return const MaterialApp(title: 'Flutter Demo',debugShowCheckedModeBanner: false, // 禁用调试标签home: BaseWidget(),);}
}// MARK: 根组件 用来处理公用逻辑
class BaseWidget extends StatefulWidget {const BaseWidget({super.key});@overrideState<BaseWidget> createState() => _BaseWidgetState();
}class _BaseWidgetState extends State<BaseWidget> {@overridevoid initState() {super.initState();// 提示回调, 要放在MaterialApp包装之后AlertCallbackManager.instance.callback = (type, message) async {if (mounted) { // 检查当前State是否仍然被挂载(即没有被dispose)if (type == AlertCallbackType.showLoading) {LoadingView().show(context);} else if (type == AlertCallbackType.hideLoading) {LoadingView().hide();} else if (type == AlertCallbackType.showToast) {ToastView.showToast(context, message);}}};}@overridevoid dispose() {LoadingView().hide();super.dispose();}@overrideWidget build(BuildContext context) {return const HomePage();}
}

然后在需要展示的地方,用如下方式调用,最好再进一步将方法封装得短一些。

AlertCallbackManager.instance.callback?.call(AlertCallbackType.showLoading, "");AlertCallbackManager.instance.callback?.call(AlertCallbackType.hideLoading, "");AlertCallbackManager.instance.callback?.call(AlertCallbackType.showToast, "message");

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/736814.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构与算法】贪心算法题解(一)

这里写目录标题 一、455. 分发饼干二、56. 合并区间三、53. 最大子数组和 一、455. 分发饼干 简单 假设你是一位很棒的家长&#xff0c;想要给你的孩子们一些小饼干。但是&#xff0c;每个孩子最多只能给一块饼干。 对每个孩子 i&#xff0c;都有一个胃口值 g[i]&#xff0c;这…

Visual Studio 2019重装vs2019打不开.netcore项目

无法打开项目文件。 .NET SDK 的版本 7.0.306 至少需要 MSBuild 的 17.4.0 版本。当前可用的 MSBuild 版本为 16.11.2.50704。请将在 global.json 中指定的 .NET SDK 更改为需要当前可用的 MSBuild 版本的旧版本。 无法打开项目文件。 .NET SDK 的版本 7.0.306 至少需要 MSBui…

【JAVA】Collections.sort()方法详解

一、简介 Collections.sort() 是 Java 集合框架&#xff08;Java Collections Framework&#xff09;中的一个静态方法&#xff0c;用于对列表&#xff08;List&#xff09;中的元素进行排序。此方法利用了 Java 的泛型机制&#xff0c;可以很方便地对各种类型的列表进行排序。…

使用gin框架,编写一个接收数据的api接口

功能&#xff1a;这里主要编写一个接口&#xff0c;将其json 数据存入对应的redis队列中&#xff0c;并统计每天的每小时请求数量 环境&#xff1a; go version go1.22.0 linux/amd64 平台 linux X64 步骤一 新建目录 命令如下&#xff1a; mkdir FormData 步骤二 新增…

当金蝶遇上BI,马上就能看到数据可视化效果

最近整理咨询内容时发现&#xff0c;很多企业用户在咨询时都会问是否有行业案例&#xff0c;究其原因时他们没用过BI数据分析&#xff0c;不知道BI可以做什么&#xff0c;能做到什么地步。其实&#xff0c;要知道这些东西还不简单&#xff0c;只需要注册奥威BI软件&#xff0c;…

CleanMyMac X 4.14.1中文版功能介绍及激活入口

细心的用户发现苹果Mac电脑越用越慢&#xff0c;其实这种情况是正常的&#xff0c;mac电脑用久了会产生很多的缓存文件&#xff0c;如果不及时清理会影响运行速度。macbook就会产生各种各样的垃圾文件,比如说残留的注册表或者无效的注册表,系统碎片以及毫无用处的文件等,这些的…

防御保护--第七次作业

题目 要求 在FW5和FW3之间建立一条IPSEC通道&#xff0c;保证10.0.2.0/24网段可以正常访问到192.168.1.0/24 过程 FW5 FW3

Cesium--基于材质旋转图片

材质部分的代码如下 // 自定义材质const customMaterial new Cesium.Material({translucent: true,fabric: {uniforms: {image:circle_img,speed:30.0,},source: czm_material czm_getMaterial(czm_materialInput materialInput){czm_material material czm_getDefaultMateri…

Python之Web开发中级教程----搭建Web框架一

准备环境&#xff1a;ubuntu,Python3.6.9 一、Web应用程序的原理 接收并解析HTTP请求&#xff0c;获取客户的请求信息->处理完成请求的业务逻辑->返回处理结果HTTP响应。 Web框架的架构是这样的&#xff1a; 基于python的web框架&#xff0c;如tornado、flask、webpy都是…

matlab去除图片上的噪声

本问题来自CSDN-问答板块,题主提问。 如何利用matlab去除图片上的噪声? 一、运行效果图 左边是原图,右边是去掉噪音后的图片。 二、中文说明 中值滤波是一种常见的图像处理技术,用于去除图像中的噪声。其原理如下: 1. 滤波器移动:中值滤波器是一个小的窗口,在图像上移…

python处理csv文件

1.使用 csv_writer.writerow # 导入CSV安装包 import csv# 1. 创建文件对象 f open(文件名.csv,a,encodingutf-8)# 2. 基于文件对象构建 csv写入对象 csv_writer csv.writer(f)# 3. 构建列表头 csv_writer.writerow(["问题","答案"])list_name[] # 4. 写…

raid0、raid1、raid5、raid10选哪个?一文给你答案!

下午好&#xff0c;我的网工朋友。 关于磁盘阵列的用法&#xff0c;总有朋友对其用途与功能一知半解&#xff0c;很容易弄混。 而我们在做监控项目存储时&#xff0c;经常会用到磁盘阵列。 什么是磁盘阵列&#xff1f;为什么要做磁盘阵列&#xff1f;用什么样的磁盘阵列合适…

Buildroot 之一 详解源码及架构

在之前的博文中,我们学习了直接通过 Makefile 手动来进行构建 U-Boot 和 Linux Kernel 等,其实,目前存在多种嵌入式 Linux 环境的构建工具,其中,Buildroot 就是被广泛应用的一种。今天就来详细学习一个 Buildroot 这个自动化构建工具。 Buildroot Buildroot 是一个运行于…

Jenkins Pipeline实现Golang项目的CI/CD

Jenkins Pipeline实现Golang项目的CI/CD 背景 最近新增了一个Golang实现的项目&#xff0c;需要接入到现有的流水线架构中。 流程图 这边流程和之前我写过的一篇《基于Jenkins实现的CI/CD方案》差不多&#xff0c;不一样的是构建现在是手动触发的&#xff0c;没有配置webho…

IOT的发展历程及其优势——青创智通

工业互联网-物联网-设备改造-IOT-青创智通 ​随着科技的不断发展&#xff0c;物联网&#xff08;IoT&#xff09;已经逐渐成为了我们生活中不可或缺的一部分。IoT是指通过互联网将各种物理设备连接起来&#xff0c;实现设备之间的数据交换和智能化控制。IoT的发展不仅改变了我们…

Window10数据库崩溃启动失败,MySQL8.0.30通过data文件夹恢复数据库到Docker

背景&#xff1a; 昨天关机前还在使用mysql&#xff0c;一切正常&#xff0c;但今天打开电脑&#xff0c;发现mysql启动不起来了&#xff0c;老是提示端口占用&#xff0c;但是系统也没有新安装什么软件&#xff0c;而且通过查询nat命令也没发现3306端口占用。而且修改成3307等…

组态软件的概念

一、前言 组态软件是一种用于设计、配置和管理自动化系统的软件。它可以帮助用户快速地创建和修改自动化系统的界面、逻辑和通信功能&#xff0c;从而提高生产效率和质量。 二、组态软件的定义 组态软件是一种集成开发环境&#xff0c;用于设计、配置和管理自动化系统。它通…

两会声音|中国石化人大代表:要突出战略性新兴产业、未来产业的位置

十四届全国人大二次会议即将闭幕&#xff0c;“新质生产力”首次写入政府工作报告&#xff0c;并出现在了重要位置。政府工作报告主要从推动产业链供应链优化升级、积极培育新兴产业和未来产业、深入推进数字经济创新发展等三个方面进行了阐述和规划。 全国两会期间&#xff0c…

2024 年系统架构设计师(全套资料)

2024年5月系统架构设计师最新第2版教材对应的全套视频教程、历年真题及解析、章节分类真题及解析、论文写作及范文、教材、讲义、模拟题、答题卡等资料 1、2023年11月最新第2版本教材对应全套教程视频&#xff0c;2022年、2021年、2020年、2018年、2016年五套基础知识精讲视频、…

搭建nacos集群,并通过nginx实现负载均衡

nacos、eureka、consul、zookeeper等都是常用的微服务注册中心&#xff0c;这篇文章详细介绍一下在Ubuntu操作系统上搭建一个nacos的集群&#xff0c;以及通过nginx的反向代理功能实现nacos的负载均衡。 目录 一、安装nacos 1、安装nacos 2、修改nacos配置文件 3、创建naco…