flutter 弹窗之系列二

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

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget 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;

  @override
  State<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,设置宽高即可
          ),
        );
      },
    );
  }


  @override
  Widget 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);

  @override
  Widget 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;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  
  @override
  Widget build(BuildContext context) {
    Loading.ctx = context; // 注入context
    return 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.mfbz.cn/a/491297.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

教程3_图像的轮廓

目录 目标 1. 特征矩 2、轮廓质心 3. 轮廓面积 4. 轮廓周长 5. 轮廓近似 6. 轮廓凸包 7. 边界矩形 7.1.直角矩形 7.2. 旋转矩形 8. 最小闭合圈 9. 拟合一个椭圆 10. 拟合直线 目标 在本文中&#xff0c;我们将学习 - 如何找到轮廓的不同特征&#xff0c;例如面积&…

【数据分享】1929-2023年全球站点的逐年平均露点(Shp\Excel\免费获取)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、能见度等指标&#xff0c;说到气象数据&#xff0c;最详细的气象数据是具体到气象监测站点的数据&#xff01; 有关气象指标的监测站点数据&#xff0c;之前我们分享过1929-2023年全球气象站…

某云盘encryptMsg 加密之自动化扣webpack

前言 本文主要介绍了webpack半自动化扣代码的流程。不需要ast基础。也不涉及加密的过程。网站硬扣的话很麻烦。特地挑一个模块多的网站去搞。着重介绍于webpack工具的使用与实现方式。 这里的话。本人也开源到了github上了。本人代码写的烂。大佬勿喷&#xff0c; https://gi…

PriorityQueue详细解读

咦咦咦&#xff0c;各位小可爱&#xff0c;我是你们的好伙伴——bug菌&#xff0c;今天又来给大家普及Java SE相关知识点了&#xff0c;别躲起来啊&#xff0c;听我讲干货还不快点赞&#xff0c;赞多了我就有动力讲得更嗨啦&#xff01;所以呀&#xff0c;养成先点赞后阅读的好…

Quartus II仿真出现错误

ModelSim executable not found in D:/intelFPGA/18.0/quartus/bin64/modelsim_ase/win32aloem/ Error. 找不到modelsim地址&#xff0c;原来是我下载了.exe,但没有双击启动安装ase文件夹呀&#xff01;&#xff01;&#xff01;&#xff01;晕&#xff0c;服了我自己

【C++11】thread线程库

【C11】thread线程库 目录 【C11】thread线程库thread类的简单介绍函数指针lambda表达式常用在线程中 线程函数参数join与detach利用RAII思想来自动回收线程 原子性操作库(atomic)atomic中的load函数&#xff1a;atomic中对变量进行原子操作的一些函数 CAS(Compare-And-Swap)无…

YOLOv5全网独家改进: 红外小目标 | 注意力改进 | 多膨胀通道精炼(MDCR)模块,红外小目标暴力涨点| 2024年3月最新成果

💡💡💡本文独家改进:多膨胀通道精炼(MDCR)模块,解决目标的大小微小以及红外图像中通常具有复杂的背景的问题点,2024年3月最新成果 💡💡💡红外小目标实现暴力涨点,只有几个像素的小目标识别率大幅度提升 改进结构图如下: 收录 YOLOv5原创自研 https://b…

jupyter lab使用虚拟环境

python -m ipykernel install --name 虚拟环境名 --display-name 虚拟环境名然后再启动jupyter lab就行了

Gitea CORS Access-Control-Allow-Origin 的问题

最近我们在想使用我们提供的代码库进行元数据提供的时候&#xff0c;启动的服务报 CORS 问题。 如果你的 Gitea 服务器是直接暴露给外部使用的话&#xff0c;可以在 Gitea 的配置文件中添加下面的配置&#xff1a; [cors] ENABLED true ALLOW_DOMAIN *在完成上面的…

【学习心得】神经网络知识中的符号解释

这里我对我学到的神经网络知识中&#xff0c;常见的符号做一下记录和总结&#xff0c;方便自己在后面学习中复习。下图二分类识别图像识别猫为例。为了保存一张图片&#xff0c;需要三个矩阵&#xff0c;它们分别对应图片中的红、绿、蓝三种颜色通道&#xff0c;如果图片大小为…

MySQL高阶SQL语句

文章目录 MySQL高阶SQL语句MySQL常用查询1、按关键字排序1.1 语法1.2 ASC和DESC1.3 对数据表中信息进行排序1.3.1 普通排序1.3.2 结合where进行条件过滤1.3.3 对多个字段进行排序 2、区间判断及查询不重复记录2.1 and/or —— 且/或2.1.1 普通查询2.1.2 嵌套/多条件查询 2.2 di…

aspect-ratio宽高比

<div class"wrapper"><div class"item">grid-tamplate-columns&#xff1a;设置容器每列的宽度(项目的宽度)grid-template-rows&#xff1a;设置容器每行的宽度(项目的高度)grid-row-gap&#xff1a;设置每行之间的行间距grid-column-gap&…

指定的文件类型无效: animExport

指定的文件类型无效: animExport 原因anim插件没有启用 你可以在 Maya 的“窗口”&#xff08;Window&#xff09;> “设置/首选项”&#xff08;Settings/Preferences&#xff09;> “插件管理器”&#xff08;Plug-in Manager&#xff09;中查看和管理插件。

⼗多种免费Unity VR资源⼯具

1、VRTK是⼀种⾼效的VR⼯具包&#xff0c;⽤于在Unity3d中快速构建VR解决⽅案VRTK - Virtual Reality Toolkit - [ VR Toolkit ] | Integration | Unity Asset StoreUse the VRTK - Virtual Reality Toolkit - [ VR Toolkit ] from Sysdia Solutions Ltd on your next project.…

蓝桥杯刷题-子串简写

子串简写 代码 kint(input()) s,c1,c2input().split() pre[0]*len(s) ans0 for i in range(len(s)):pre[i]pre[i-1]if c1s[i]:pre[i]1elif c2s[i] and i1-k>0:anspre[i-k1] print(ans)

亲测有效Djiango连接oracle

navicat连接本地oracle截图。 Djiango下面settings.py下面的DATABASES&#xff1a; 注意&#xff1a;USER最好不要用sys或者system可能会导致连接不了&#xff0c;最好是自己新建的oracle用户。

Linux一键式安装JDK、Mysql、Redis、Nginx(附带安装包,无需手动配置密码等)

安装包 新服务器安装前置准备 1. 设置系统时区 # 查看服务器时区 timedatectl # 设置服务器时区为上海 timedatectl set-timezone Asia/Shanghai # 设置系统时间为“2021-3-19 11:00:00” date -s "2021-3-19 11:00:00" # 查看校准后的系统时间 date …

笔记本如何调节亮度?笔记本亮度调节方法

对于经常长时间面对笔记本电脑的小伙伴们来说&#xff0c;屏幕亮度过暗或者过亮&#xff0c;都会对眼睛造成伤害。那么&#xff0c;我们如何调节笔记本亮度至适中呢?下面为大家介绍3种简单的调节屏幕亮度的方法&#xff0c;一起来看看吧! 笔记本亮度调节方法一&#xff1a; 1、…

element-ui input 组件源码分享

今日简单分享 input 组件的实现原理&#xff0c;主要从以下五个方面来分享&#xff1a; 1、input 组件的页面结构 2、input 组件的属性 3、input 组件的 slot 4、input 组件的事件 5、input 组件的方法 一、input 组件的页面结构。 二、input 组件的属性。 2.1 type 属性…

Eclipse新建java类的操作流程

一、在左侧空白区域&#xff0c;点击鼠标右键。 二、点击new&#xff0c;选择Java Project &#xff08;由于这里不知道怎么截图&#xff0c;就用手机拍了一张&#xff0c;希望不要介意&#xff09; 三、 给project文件起个名字&#xff0c;其他都不用管&#xff0c;点击Finis…
最新文章