Flutter dialog (1) - showDialog的讲解

article/2025/11/11 2:28:54

在应用开发中,或多或少都会遇到需要弹框的问题, 比如:需要用户确认,需要输入一些信息等等的问题,这就要用到 dialog 相关的概念了

而在 flutter 中,所有可以看见的都是 Widget,dialog 也不例外

不过和 android 或 iOS 中不同的一点是,Flutter 中 dialog 不是一个单独的类,而是一个可以由你自定义的 Widget

写在前面

首先为了方便,我定义了一个简单的方法用于构建按钮

  Widget buildButton(String text,Function onPressed, {Color color = Colors.white,}) {return FlatButton(color: color,child: Text(text),onPressed: onPressed,);}

showDialog

20190327134903.png
dialog 的方法签名是这样的

其中 context 和 builder 是必传项

builder 需要返回一个 Widget,这个 Widget 会被作为 dialog 展示在页面上

比如我简单的写了一个这个方法

    showDialog(context: context,builder: (ctx) {return Center(child: Column(mainAxisSize: MainAxisSize.min,children: <Widget>[buildButton("返回1", () {}),buildButton("返回2", () {}),],),);},);

当我调用这个方法时,会得到这样的样式
20190327140047.png

这个就是最简单的方法,然后点击外部,dialog 会消失

添加关闭时的返回值

接着我给按钮添加具体的事件

修改代码为以下的样子

_showDialog() async {var result = await showDialog(context: context,builder: (ctx) {return Center(child: Column(mainAxisSize: MainAxisSize.min,children: <Widget>[buildButton("返回1", () => Navigator.of(context).pop(1)),buildButton("返回2", () => Navigator.pop(context, 2)),],),);},);print("result = $result");}

然后分别点击 1 2 和外部让 dialog 消失
会得到以下的结果

20190327140439.png

不过这个只能让 dialog 显示固定的内容,如果你的 dialog 有内容变化,则使用这个方式就不行了,哪怕是调用 setState 也不会发生变化,这个是因为外部 State 的状态变化不会影响到 dialog 的内容,因为 dialog 是附着至 app 根部的,而不是附着于页面

20190327141927.png

结合 StatefulWidget 使用

所以我们 dialog 中也可以使用 StatefulWidget,如同一个页面一样,只是这个页面可能不是全屏的

我定义了一个简单的 CounterWidget


class CounterWidget extends StatefulWidget {@override_CounterWidgetState createState() => _CounterWidgetState();
}class _CounterWidgetState extends State<CounterWidget> {var _counter = 0;@overrideWidget build(BuildContext context) {return Center(child: Column(mainAxisSize: MainAxisSize.min,children: <Widget>[Material(child: Container(width: 100,height: 100,child: Text(_counter.toString(),style: TextStyle(fontSize: 40),),alignment: Alignment.center,),color: Colors.white,),buildButton("+1", () => setState(() => _counter++)),buildButton("-1", () => setState(() => _counter--)),],),);}
}

并且调用

showDialog(context: context, builder: (ctx) => CounterWidget());

Kapture 2019-03-27 at 14.26.15.gif

这里可以看到,一个带状态的控件也是可以被展示在 dialog 中的

结合 StatefulBuilder

在 flutter 中有一个类,叫 StatefulBuilder

这个类的 builder 构造中会给一个 state,这个 state 是一个方法,返回 void,传入参数是一个方法,听起来很绕

大概是这样用

var statefulBuilder = StatefulBuilder(builder: (ctx, state) {state(() {});return Container();},
);

看起来和 setState 很像

这里我模拟一个 progress 的变化,不过这个进度是由外部传入的

_showDialogWithStatefulBuilder() {var progress = 0.0;StateSetter ss;Timer.periodic(Duration(milliseconds: 300), (timer) {progress += 0.1;if (ss != null) {ss(() {});}if (progress >= 1) {timer.cancel();ss = null;}});var sb = StatefulBuilder(builder: (ctx, state) {ss = state;return Center(child: Container(height: 40,child: LinearProgressIndicator(backgroundColor: Colors.white,value: progress,),),);},);showDialog(context: context, builder: (ctx) => sb);}

Kapture 2019-03-27 at 14.49.52.gif

这里只是简单的演示一个用法,实际应用中,进度条应该是可以多处复用的,应该使用 StatefulWidget 进行复用,而不是简易的使用 StatefulBuilder 来做这件事情,并且,应该在构建时传入 stream 并且监听 stream 为宜,而不应该使用这种 Timer 的形式

StatefulBuilder 应该用于弹出布局很特殊不太可能复用于其他地方的情况

使用 iOS 风格

有的同学可能要问了,你这演示都是 MD 风格的,我需要的是苹果风格的, 怎么办?

在 flutter 中,如果你需要 iOS 风格的,只需要使用 Cupertino 组件即可

void showCupertinoDialog() {var dialog = CupertinoAlertDialog(content: Text("你好,我是你苹果爸爸的界面",style: TextStyle(fontSize: 20),),actions: <Widget>[CupertinoButton(child: Text("取消"),onPressed: () {Navigator.pop(context);},),CupertinoButton(child: Text("确定"),onPressed: () {Navigator.pop(context);},),],);showDialog(context: context, builder: (_) => dialog);}

20190327145558.png

带输入框的 dialog

 showHasInputDialog() {var widget = Center(child: Container(height: 40,width: double.infinity,child: Material(child: TextField(),),),);showDialog(context: context, builder: (_) => widget);}

20190327150012.png

根据软键盘自动变化位置

之前的输入框有一些问题,如果你的弹窗在底部,则弹出的输入框可能会被挡住

这里需要另一个方法来实现

import 'package:flutter/material.dart';
import 'dart:ui' as ui;class InputDialog extends StatefulWidget {@override_InputDialogState createState() => _InputDialogState();
}class _InputDialogState extends State<InputDialog> with WidgetsBindingObserver {@overridevoid initState() {super.initState();WidgetsBinding.instance.addObserver(this);}@overridevoid dispose() {WidgetsBinding.instance.removeObserver(this);super.dispose();}@overridevoid didChangeMetrics() {super.didChangeMetrics();if (this.mounted) setState(() {});}@overrideWidget build(BuildContext context) {var mediaQueryData = MediaQueryData.fromWindow(ui.window);return AnimatedContainer(color: Colors.transparent,duration: const Duration(milliseconds: 300),padding: EdgeInsets.only(bottom: mediaQueryData.viewInsets.bottom),child: Material(child: TextField()),alignment: Alignment.center,);}
}

定义一个 dialog 类,然后监听窗口的变化

然后在变化的时候动态的修改 padding,以达到输入框永远在界面中心的目的

Kapture 2019-03-27 at 15.16.40.gif

后记

完整代码 github

第一篇主要讲了 showDialog 方法的一些使用方法和建议

以上


http://chatgpt.dhexx.cn/article/RaVoP8pQ.shtml

相关文章

C# 按Button弹出新的窗体 Show()方法 和 ShowDialog()方法

在做串口通信程序时&#xff0c;有个想法&#xff0c;当点击串口设置按钮时&#xff0c;弹出一个新的窗口&#xff0c;可以设置串口相关信息&#xff0c;如何实现这一操作呢&#xff1f; 1 新建一个项目&#xff0c;窗体为form1 2 选择项目名称&#xff0c;单击右键&#xff0…

C# 弹出窗口 show()和showdialog()

目录 一、构建工程和界面介绍二 、添加代码三、验证效果和小结 我们在构建C# Form窗口的时候经常需要到弹出新的窗口&#xff0c;那么接着就会如何弹出窗口的疑问。这里介绍最常见的两种弹窗方法show()和showdialog()。我在VS2019中构建一个简单的工程来讲解让他们之间的区别。…

fwrite函数,fread函数和fgets函数详解以及使用方法

c/c文件处理函数 1. fgets函数 函数原型 char *fgets(char *s, int size, FILE *stream);参数解释&#xff1a; s 代表要保存到的内存空间的首地址&#xff0c;可以是字符数组名&#xff0c;也可以是指向字符数组的字符指针变量名。size 代表的是读取字符串的长度。stream …

c语言 fread读指定字节,fread函数 c语言中fread函数怎么用

fread是一个函数,它从文件流中读数据,最多读取count个项,每个项size个字节,如果调用成功返回实际读取到的项个数(小于或等于count),如果不成功或读到文件末尾返回0。返回真实读取的项数,若大于count则意味着产生了错误。另外,产生错误后,文件位置指示器是无法确定的。若…

c语言fread函数,C语言“fread”函数的用法?

C语言“fread”函数的用法? C语言“fread”函数的用法为“size_tf read(void *buffer,size_t size,size_t count,FILE *stream)”,其作用是从一个文件流中读数据,读取count个元素,每个元素size字节。 示例1#include #include #include int main() {FILE *stream; char m…

【C 语言】文件操作 ( fread 函数 )

文章目录 一、fread 函数二、缓冲区受限的情况 ( 循环读取文件 | feof 函数判定文件读取完毕 )三、处理乱码问题四、记录读取的字节个数五、读取到 0 字节的情况六、读取完毕的情况七、读取文本文件 " " 与 读取二进制文件 " " 区别 二进制文件读写两个重…

Scala对象 转Json字符串

2019独角兽企业重金招聘Python工程师标准>>> import org.json4s.{Formats, NoTypeHints} import org.json4s.jackson.Serialization import org.json4s.jackson.Serialization.writeobject Json4sDemo {// 需要添加隐式转换implicit val formats: AnyRef with Forma…

【系统学习SpringBoot】SpringBoot 对象转JSON输出

SpringBoot输出JSON 以往使用SpringMVC中开发时&#xff0c;对象转JSON需要配置很多东西 【1】添加FastJson/jackjson等第三方jar 【2】在配置文件中配置Controller扫描 【3】给方法添加ResponseBody 配置FastJson还需要给配置文件中添加(很麻烦( ▼-▼ )) <mvc:annot…

【Java 笔记】使用Fastjson2时,对象转json首字母大小写问题

开发环境&#xff1a; Spring cloud Fastjson2 一、JSON 转 Object 推送第三方数据时&#xff0c;对方http接口消息体为json&#xff0c;但是字段首字母大写 我们需要接收JSON 转 Object [ { "ItemCode": "WIND_SPEED", "ItemValue": "2.1…

js 数组、对象转json 以及json转 数组、对象

1、JS对象转JSON 方式&#xff1a;JSON.stringify(obj) var json {"name":"iphone","price":666}; //创建对象&#xff1b; var jsonStr JSON.stringify(json); //转为JSON字符串 console.log(jsonStr);2、JS数组转JSON //数组转json…

对象转JSON首字母大写

最近在做一个第三方接口&#xff0c;接口给的数据类型如下 请求报文如下 {"A0144":"12141256","AB6AM":"中国银行支行","STATUS":1} 一般按照对象转JSON会使首字母小写&#xff0c;与接口文档不相符&#xff0c;因此需要…

Object对象转实体对象,java对象转json

Object对象转实体对象 在后台发起HTTP请求的时候&#xff0c;响应体传回的一般是Object或者JSON字符串。 方法一 要将Object对象转换成实体类对象可以先使用com.alibaba.fastjson.JSONObject类的toJSONString方法将Object对象转换成JSON字符串&#xff0c;然后再调用JSONObj…

对象 和 json 互转 四种方式 json-lib、Gson、FastJson、Jackson

文章目录 一、 json-lib二、 Google的Gson1.简介2. 配置步骤1. MAVEN 依赖引入2. gsonUtil 工具类3. 排除不要序列化的熟悉注解类 Exclude 三. 阿里巴巴的FastJson1.简介2.配置步骤1.引入maven2. 配置 CustomFastjsonConfig3. 测试 4. 开源的Jackson简介&#xff1a;Jackson配置…

大数据Java学哪个好,哪个更有发展前景?

文章来源&#xff1a;加米谷大数据 在IT职业技能培训当中&#xff0c;Java开发可以说是非常经典的一个方向&#xff0c;行业当中对于Java开发人才&#xff0c;早年可以是存在长期持续性的需求。而大数据&#xff0c;作为近年来的新兴技术热点&#xff0c;也同样备受关注。因此很…

大数据Java基础之常用类

欢迎关注公众号&#xff1a; 9-1 字符串相关的类 String常用方法 9-2 JDK8之前日期时间API 9-4 Java比较器 9-5 System类 9-6 Math类 9-7 BigInteger与BigDecimal

Java毕设项目医疗大数据系统计算机(附源码+系统+数据库+LW)

Java毕设项目医疗大数据系统计算机&#xff08;附源码系统数据库LW&#xff09; 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项…

方向选择(嵌入式 大数据 java)

时间匆匆&#xff0c;不知不觉大二后半期了。晚上开了会要确定方向选择&#xff0c;嵌入式&#xff0c;大数据&#xff0c;java三个方向。 犹豫了好久&#xff0c;因为学了一段时间的java还是偏向于java的 不过也想学大数据&#xff0c;因为最近很火 大家都 知道的。现在来简…

大数据入门:Java和Scala编程对比

在学习大数据之初&#xff0c;很多人都会对编程语言的学习有疑问&#xff0c;比如说大数据编程主要用什么语言&#xff0c;在实际运用当中&#xff0c;大数据主流编程是Java&#xff0c;但是涉及到Spark、Kafka框架&#xff0c;还需要懂Scala。今天的大数据入门分享&#xff0c…

视频教程-大数据Java强化班(十)之大数据爬虫-Java

大数据Java强化班(十)之大数据爬虫 10年一线开发及项目管理经验&#xff0c;6年以上大数据项目架构、实施、开发与运维经验&#xff0c;骨灰级大数据玩家&#xff0c;对Hadoop、Storm、Spark、Flink、Kylin、Druid等大数据技术有较深研究。搭建、维护过上百节点集群&#xff0c…