本文共 3820 字,大约阅读时间需要 12 分钟。
flutter中使用弹窗应该用flutter提供的showDialog方法
void _showAlertDialog() async { var res = await showDialog( context: context, child: AlertDialog( title: Text('测试'), content: Text('这是一个测试窗口'), actions: [ FlatButton( onPressed: () { Navigator.of(context).pop(); }, child: Text('确定')), FlatButton( onPressed: () { Navigator.of(context).pop(); }, child: Text('取消')) ], )); print(res); }
这里我们调用了showDialog()方法,传入参数:
在AlertDialog中,我们添加了一个title,content,以及两个按钮。按钮的点击事件,我们添加了
Navigator.of(context).pop();
点击两个按钮后,都会退出弹框。
运行结果:
而res的结果为null,原因是因为我们退出时并没有指定参数,我们也可以给它指定一个参数,类似于这样:Navigator.of(context).pop("test");
这时候res的结果就会使test了
上面说了,showDialog()的child参数是一个组件,所以我们的自定义弹窗要继承自statelesswidget或者statefullwidget
/* * @Author: wangyuyong * @Date: 2020-07-21 09:24:59 * @LastEditTime: 2020-07-21 13:59:36 * @FilePath: /flutterdemo/lib/components/LoadingDialog.dart * @Description: */import 'package:flutter/material.dart';class LoadingDialog extends StatefulWidget { final Color _valueColor; final String _content; _LoadingDialogState state; LoadingDialog( {Key key, Color valueColor = Colors.red, String content = "加载中..."}) : this._valueColor = valueColor, this._content = content, super(key: key); @override _LoadingDialogState createState() => state = _LoadingDialogState( valueColor: this._valueColor, content: this._content, ); bool isLoading() { return state._isActive; }}class _LoadingDialogState extends State{ final Color _valueColor; final String _content; bool _isActive = false; _LoadingDialogState( {Color valueColor = Colors.red, String content = "加载中..."}) : this._valueColor = valueColor, this._content = content; void initState() { // loading弹窗当前为活跃界面 super.initState(); this._isActive = true; } @override Widget build(BuildContext context) { return Material( // 设置透明 type: MaterialType.transparency, child: Center( child: Container( width: 200, height: 200, color: Colors.white, child: Stack( children: [ Align( child: CircularProgressIndicator( strokeWidth: 4.0, valueColor: new AlwaysStoppedAnimation(this._valueColor), ), alignment: Alignment.center, ), Align( child: Padding( padding: EdgeInsets.fromLTRB(10, 10, 10, 20), child: Text(this._content), ), alignment: Alignment.bottomCenter, ) ], ), ), ), ); } @override void dispose() { // TODO: implement dispose super.dispose(); this._isActive = false; }}
在build中,我们使用Material这个组件,同时设置它的type为MaterialType.transparency,这样子就可以实现弹窗的背景是那种黑色半透明的效果了,接着就是一些常规布局了。
圆形进度条我们使用CircularProgressIndicator组件CircularProgressIndicator( strokeWidth: 4.0, valueColor: new AlwaysStoppedAnimation(this._valueColor), ),
这里我们还需要提供一个isLoading的方法给外面调用,如果dialog没有处于界面,则不调用Navigator.of(context).pop(),如果dialog处于界面,在数据加载完成后,才能调用Navigator.of(context).pop()。
我们来使用一下这个弹窗:void _showLoadingDialog() async { var dialog = LoadingDialog(); showDialog(context: context, child: dialog); Timer.periodic(Duration(milliseconds: 3000), (t) { t.cancel(); if (dialog.isLoading()) { Navigator.of(context).pop(); } });
这里我使用了一个计时器Timer来模仿网络请求,演示结果:
略(嘿嘿嘿~没法上传视频,就不演示了)到此,水文结束
转载地址:http://ddtzi.baihongyu.com/