flutter 弹窗之系列二

自定义弹窗(含底部抽屉)Dialog

class MyHomePage extends StatefulWidget {const MyHomePage({super.key, required this.title});final String title;@overrideState<MyHomePage> createState() => _MyHomePageState();
}class _MyHomePageState extends State<MyHomePage> {@overrideWidget build(BuildContext context) {return Scaffold(body: Column(mainAxisAlignment: MainAxisAlignment.spaceAround,crossAxisAlignment: CrossAxisAlignment.center,children: [const SizedBox(height: 0,width: double.infinity,),TextButton(child: const Text("show dialog"),onPressed: () => showCustomDialog(),),TextButton(child: const Text("show delay dialog"),onPressed: () => showDelayDialog(),),TextButton(child: const Text("show sheet"),onPressed: () => showSheetDialog(),),],),);}void showCustomDialog() {CustomDialog.show(context, (context, dismiss) {return Container(width: 200,height: 100,color: Colors.white,child: Center(child:TextButton(onPressed: () => dismiss(), child: const Text("POP")),),);});}void showSheetDialog() {CustomDialog.showBottomSheet(context, (ctx, dismiss) {return Container(height: 300,color: Colors.white,margin: const EdgeInsets.all(20),child: Center(child:TextButton(onPressed: () => dismiss(), child: const Text("POP")),),);});}void showDelayDialog() {CustomDialog.show(context, (context, dismiss) {//延时关闭Timer(const Duration(seconds: 2), () => dismiss());return Container(width: 200,height: 100,color: Colors.yellow,child: const Center(child: Text("等待"),),);}, cancellable: true);}
}class CustomDialog {static void show(BuildContext context,Widget Function(BuildContext ctx, void Function() dismiss) builder,{bool cancellable = false}) {showDialog(context: context,barrierDismissible: cancellable,builder: (ctx) {return WillPopScope(child: Dialog(child: builder(ctx, () => Navigator.of(ctx).pop()),backgroundColor: Colors.transparent,shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(0.0))),elevation: 0,alignment: Alignment.center,),onWillPop: () async => cancellable,);},);}static void showBottomSheet(BuildContext context,Widget Function(BuildContext ctx, void Function() dismiss) builder,{bool cancellable = true}) {showModalBottomSheet(context: context,isDismissible: cancellable,enableDrag: cancellable,isScrollControlled: true,builder: (BuildContext ctx) {return WillPopScope(child: builder(ctx, () => Navigator.of(ctx).pop()),onWillPop: () async => cancellable,);},//不设置会默认使用屏幕最大宽度而不是子组件宽度constraints: const BoxConstraints(minWidth: 0,minHeight: 0,maxWidth: double.infinity,maxHeight: double.infinity),backgroundColor: Colors.transparent,);}
}

AlertDialog的属性

  • title:标题
  • titlePadding:标题内边距
  • titleTextStyle:标题样式
  • content:内容,推荐用SingleChildScrollView包裹
  • contentPadding:EdgeInsets.fromLTRB(24.0, 20.0, 24.0, 24.0),内容内边距
  • contentTextStyle:内容样式
  • actions:按钮集合,可以放多个
  • actionsPadding:EdgeInsets.zero,actions内边距
  • buttonPadding:按钮内边距
  • backgroundColor:背景色
  • elevation:阴影
  • shape:形状
  • scrollable = false:

 SimpleDialog

  • title:标题
  • titlePadding:EdgeInsets.fromLTRB(24.0, 24.0, 24.0, 0.0),标题内边距
  • titleTextStyle:标题样式
  • children:子节点
  • contentPadding:EdgeInsets.fromLTRB(0.0, 12.0, 0.0, 16.0),内容内边距
  • backgroundColor:背景色
  • elevation:阴影
  • shape:形状

 全局弹窗

  • pubspec.yaml增加dio依赖包
dio: any # dio依赖包

 

class MyHomePage extends StatefulWidget {const MyHomePage({super.key, required this.title});final String title;@overrideState<MyHomePage> createState() => _MyHomePageState();
}class _MyHomePageState extends State<MyHomePage> {void _showLoadingDialog() {showDialog(context: context,builder: (context) {// 用Scaffold返回显示的内容,能跟随主题return Scaffold(backgroundColor: Colors.transparent, // 设置透明背影body: Center( // 居中显示child: Column( // 定义垂直布局mainAxisAlignment: MainAxisAlignment.center, // 主轴居中布局,相关介绍可以搜下flutter-ui的内容children: <Widget>[// CircularProgressIndicator自带loading效果,需要宽高设置可在外加一层sizedbox,设置宽高即可CircularProgressIndicator(),SizedBox(height: 10,),Text('loading'), // 文字// 触发关闭窗口GestureDetector(child: Text('close dialog'),onTap: () {print('close');},),],), // 自带loading效果,需要宽高设置可在外加一层sizedbox,设置宽高即可),);},);}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(backgroundColor: Theme.of(context).colorScheme.inversePrimary,title: Text(widget.title),),body: Center(child: GestureDetector(onTap: () {_showLoadingDialog();},child: const Text('\n点击显示弹窗一\n',),),),);}
}

接入dio 网络请求显示弹窗

import 'package:dio/dio.dart' show Dio, InterceptorsWrapper;
import 'package:flutter_custom_widget/http/Loading.dart';Dio? dio;class Http {static Dio? instance() {if (dio != null) {return dio;// 实例化dio}dio = Dio();// 增加拦截器dio?.interceptors.add(InterceptorsWrapper(// 接口请求前数据处理onRequest: (options,handler) {Loading.before("onRequest");},// 接口成功返回时处理onResponse: (resp,handler) {Loading.complete();},// 接口报错时处理onError: ( error,handler) {Loading.complete();},),);return dio;}/// get接口请求/// path: 接口地址static get(path) {return instance()?.get(path);}
}

import 'package:flutter/material.dart';class Loading {static dynamic ctx;static void before(text) {// 请求前显示弹窗showDialog(context: ctx,builder: (context) {return Index(text: text);},);}static void complete() {// 完成后关闭loading窗口Navigator.of(ctx, rootNavigator: true).pop();}
}// 弹窗内容
class Index extends StatelessWidget {final String? text;Index({Key? key, @required this.text}):super(key: key);@overrideWidget build(BuildContext context) {return  Text('$text');}
}

实现全局存储context

@override
Widget build(BuildContext context) {......Loading.ctx = context; // 注入context......}
class Loading {static dynamic ctx;static void before(text) {// 请求前显示弹窗// showDialog(context: ctx, builder: (context) {//   return Index(text:text);// );}static void complete() {// 完成后关闭loading窗口// Navigator.of(ctx, rootNavigator: true).pop();}
}

实现dio请求时loading

class MyHomePage extends StatefulWidget {const MyHomePage({super.key, required this.title});final String title;@overrideState<MyHomePage> createState() => _MyHomePageState();
}class _MyHomePageState extends State<MyHomePage> {@overrideWidget build(BuildContext context) {Loading.ctx = context; // 注入contextreturn Scaffold(appBar: AppBar(backgroundColor: Theme.of(context).colorScheme.inversePrimary,title: Text(widget.title),),body: Center(child: GestureDetector(onTap: () {Http.get('https://blog.csdn.net/u013491829/article/details/137032263');},child: const Text('\n点击进行网络加载\n',),),),);}
}

并发请求时loading处理

并发请求,loading只需要保证有一个在当前运行。接口返回结束,只需要保证最后一个完成时,关闭loading。 

  • 使用Set有排重作用,比较使用用来管理并发请求地址。通过Set.length控制弹窗与关闭窗口。
  • 增加LoadingStatus判断是否已经有弹窗存在
  • 修改onRequest/onResponse/onError入参
import 'package:flutter/material.dart';Set dict = Set();
bool loadingStatus = false;
class Loading {static dynamic ctx;static void before(uri, text) {dict.add(uri); // 放入set变量中// 已有弹窗,则不再显示弹窗, dict.length >= 2 保证了有一个执行弹窗即可,if (loadingStatus == true || dict.length >= 2) {return ;}loadingStatus = true; // 修改状态// 请求前显示弹窗showDialog(context: ctx,builder: (context) {return Index(text: text);},);}static void complete(uri) {dict.remove(uri);// 所有接口接口返回并有弹窗if (dict.length == 0 && loadingStatus == true) {loadingStatus = false; // 修改状态// 完成后关闭loading窗口Navigator.of(ctx, rootNavigator: true).pop();}}
}

 案例 切换到分支flutter_custom_widget

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

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

相关文章

2024-03-26 AIGC-大模型学习路线

摘要: 2024-03-26 AIGC-大模型学习路线 大模型学习路线 建议先从主流的Llama开始&#xff0c;然后选用中文的Qwen/Baichuan/ChatGLM&#xff0c;先快速上手体验prompt工程&#xff0c;然后再学习其架构&#xff0c;跑微调脚本 如果要深入学习&#xff0c;建议再按以下步骤&am…

云手机:实现便携与安全的双赢

随着5G时代的到来&#xff0c;云手机在各大游戏、直播和新媒体营销中扮演越来越重要的角色。它不仅节约了成本&#xff0c;提高了效率&#xff0c;而且在边缘计算和云技术逐渐成熟的背景下&#xff0c;展现出了更大的发展机遇。 云手机的便携性如何&#xff1f; 云手机的便携性…

企业微信应用结合Cpolar内网穿透实现固定域名验证回调本地接口服务

文章目录 1. Windows安装Cpolar2. 创建Cpolar域名3. 创建企业微信应用4. 定义回调本地接口5. 回调和可信域名接口校验6. 设置固定Cpolar域名7. 使用固定域名校验 企业微信开发者在应用的开发测试阶段&#xff0c;应用服务通常是部署在开发环境&#xff0c;在有数据回调的开发场…

k8s入门到实战(四)—— k8s核心概念以及基本操作命令详细介绍

k8s 核心概念及操作命令 namespace&#xff08;命名空间&#xff0c;简称 ns&#xff09; k8s 资源创建的两种方式&#xff1a;使用命令行创建、使用 yaml 文件创建 什么是 ns 在 k8s 中&#xff0c;ns 是一种用于对集群资源进行逻辑分组和隔离的机制。它允许将 k8s 集群划…

torch.utils.data.DataLoader参数分析

1、dataset&#xff1a;&#xff08;数据类型 dataset&#xff09; 输入的数据类型,这里是原始数据的输入。PyTorch内也有这种数据结构。 2、batch_size&#xff1a;&#xff08;数据类型 int&#xff09; 批训练数据量的大小&#xff0c;根据具体情况设置即可&#xff08;默…

Elasticsearch8 - Docker安装Elasticsearch8.12.2

前言 最近在学习 ES&#xff0c;所以需要在服务器上装一个单节点的 ES 服务器环境&#xff1a;centos 7.9 安装 下载镜像 目前最新版本是 8.12.2 docker pull docker.elastic.co/elasticsearch/elasticsearch:8.12.2创建配置 新增配置文件 elasticsearch.yml http.host…

16 网络管理与网络安全(3)

1.公钥基础设施&#xff08; PKI&#xff09; PKI 是利用公钥加密和数字签名技术建立的安全服务基础设施&#xff0c;以保证网络环境中数据的秘密性、完整性与不可抵赖性。PKI 是一种针对电子商务、电子政务应用&#xff0c;利用非对称加密体系&#xff0c;提供安全服务的通用性…

微信聊天记录删了怎样才能恢复?揭秘4个宝藏方法

在我们使用微信进行聊天的过程中&#xff0c;不可避免地会出现误删聊天记录的情况&#xff0c;这可能是因为手误、设备问题或其他原因导致的。而当重要的聊天记录不慎被删除时&#xff0c;往往会让人感到焦虑和困扰。然而&#xff0c;幸运的是&#xff0c;针对被删除的微信聊天…

函数式编程的理解

函数式编程&#xff08;Functional Programming&#xff0c;简称FP&#xff09;是一种编程范式&#xff0c;它将计算视为数学函数的求值&#xff0c;并避免使用程序状态以及易变对象。这种编程风格强调不可变性&#xff08;Immutability&#xff09;、纯函数&#xff08;Pure F…

Java基础--128陷阱

问题引入 Integer a 123; Integer b 123; System.out.println(ab); 结果为true。 但是如果代码如下 Integer a 1230;Integer b 1230;System.out.println(ab); 这个的结果就是false。 问题解决 当Integer a 123时&#xff0c;其实他底层自动转换成了Integer a Inte…

docker--Dockerfile (三)

1&#xff0c;Dcockerfile是什么 docker推荐使用dockerfile的定义文件和docker build命令来构建镜像。dockerfile使用基本的基于DSL&#xff08;面向领域语言&#xff09;语法的指令来构建Docker镜像。另一种创建Docker镜像的方式是使用docker commit&#xff0c;不推荐使用。 …

【python】flask执行上下文context,请求上下文和应用上下文原理解析

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

SqlServer期末复习(数据库原理及应用)持续更新中

一、SQL语句 1.1 SQL语句知识引入 1.DDL语言(数据定义语言&#xff09;主要是进行定义/改变表的结构、数据类型、表之间的链接等操作&#xff0c;关键字CREATE、DROP、ALTER CREATE TABLE 表面( 列名1 数据类型&#xff0c; 列名2 数据类型&#xff0c; ) ALTER TABLE 表名&a…

掌控仓位管理之道 稳健操作赢得长期收益

作为投资领域资深从业者,刘国海老师拥有顶尖学府香港中文大学和纽约大学的高等教育背景,通过20余年的金融投资实战,累积了大量操作经验,对市场行情亦有精准洞察。 在漫长投资历程中,刘国海老师一直高度重视仓位管理,视之为获取稳健收益的重中之重。合理仓位是投资收益与风险之…

MFC 打开类向导中方法时提示对com组件的调用返回了错误 HRESULT E_FAIL

解决&#xff1a;头文件中要分类&#xff0c;把virtual和afx_msg等放在一起&#xff0c;不要交叉错开。 MFC&#xff08;Microsoft Foundation Class&#xff09;中的virtual关键字用于声明虚函数。虚函数是C中实现多态的一种机制&#xff0c;它允许派生类重新定义基类中的虚函…

【算法刷题day6】Leetcode:242. 有效的字母异位词、349. 两个数组的交集、202. 快乐数、1. 两数之和

文章目录 Leetcode 242. 有效的字母异位词解题思路代码总结 Leetcode 349. 两个数组的交集解题思路代码总结 Leetcode 202. 快乐数解题思路代码总结 Leetcode 1. 两数之和解题思路代码总结 HashSet基本使用&#xff1a;HashMap基本使用&#xff1a; 草稿图网站 java的Deque Le…

java面试题|(1)多线程如何停止一个线程?

在Java中&#xff0c;停止一个线程的方法通常有以下几种&#xff1a; 使用标志位停止线程&#xff1a; 这是一种常见的做法&#xff0c;即通过设置一个标志位&#xff0c;在线程的执行体中检查这个标志位&#xff0c;当标志位满足某个条件时&#xff0c;退出线程执行。 class M…

那位拿了多个Offer的大佬分享了最新Go面经

和大家分享一下我们 Go就业训练营 和 升职加薪星球 中战友们投稿的真实面经。 这是第一篇&#xff0c;计划还会再更新4篇最新Go面经&#xff0c;都是拿到Offer的那种&#xff01; 欢迎大家关注我的账号&#xff0c;关注之后不迷路。 先秀战绩 虽然不同的公司考察的侧重点不一…

每日必学Linux命令:mv命令

mv命令是move的缩写&#xff0c;可以用来移动文件或者将文件改名&#xff08;move (rename) files&#xff09;&#xff0c;是Linux系统下常用的命令&#xff0c;经常用来备份文件或者目录。 一&#xff0e;命令格式&#xff1a; mv [选项] 源文件或目录 目标文件或目录二&am…

计算机基础(中断、IO)

操作系统 设备交互 CPU 与 IO 设备交互过程 CPU 通过设备控制器&#xff08;驱动&#xff1f;&#xff09;与计算机外设进行交互。可以将控制器想象成编程语言中的接口&#xff0c;然后不同地计算机外设的控制器去实现这个接口&#xff0c;CPU 只需要调用接口而无需关注具体地…