前言
showDialog 是 flutter 中一个展示 Material 风格对话框函数,正常情况下使用对话框,都是有相应对交互逻辑的,当我们需要改变某个属性的状态时,通常情况下会发现 setState() 无法使用。
场景
一般情况下我们使用 showDialog 的代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| showDialog( context: context, builder: (BuildContext context){ return Container( child: Scaffold( body: Column( children: <Widget>[ ... ], ), ), ); } );
|
在这种情况下如果使用 setState() 会发现通过 setState() 更新的属性不会生效。
解决
如何解决这个问题呢?有两个解决办法。在 dialog 中声明一个 StatefulBuilder 或者 StatefulWidget。可以看一下具体的例子:
StatefulBuilder 样例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| await showDialog<void>( context: context, builder: (BuildContext context) { int selectedRadio = 0; return AlertDialog( content: StatefulBuilder( builder: (BuildContext context, StateSetter setState) { return Column( mainAxisSize: MainAxisSize.min, children: List<Widget>.generate(4, (int index) { return Radio<int>( value: index, groupValue: selectedRadio, onChanged: (int value) { setState(() => selectedRadio = value); }, ); }), ); }, ), ); }, );
|
重点在6,7行代码
自定义一个 StatuefulWidget 的组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| class Bird extends StatefulWidget { const Bird({ Key key, this.color = const Color(0xFFFFE306), this.child, }) : super(key: key);
final Color color; final Widget child;
_BirdState createState() => _BirdState(); }
class _BirdState extends State<Bird> { double _size = 1.0;
void grow() { setState(() { _size += 0.1; }); }
@override Widget build(BuildContext context) { return Container( color: widget.color, transform: Matrix4.diagonal3Values(_size, _size, 1.0), child: widget.child, ); } }
|
参考
Flutter: setState on showDialog()