网站建设开发成本seo关键词排名注册价格
前言
最近基于想实现一个个人常用功能集合的APP了解到了跨平台方案。进而开始了对Flutter的学习,通过文章记录一下学习中的收获。
本篇文章的主要内容是对Flutter中状态管理的方式及不同方式的选择进行介绍。
本文首发于我的个人博客 技术公馆(wcc.im) : Flutter状态管理初探
目录
状态管理的方式
常见的状态管理方式有三种,分别是由Widget自身进行管理,由父Widget进行管理和由Widget自身及父Widget混合进行管理。
在对三种常见的状态管理方式进行分析时,我们定义了3个Tapbox,每个Tapbox可表示激活与未激活。这样Tapbox就是一个有状态的Widget。
由Widget自身进行管理
//------------------------- TapboxA ----------------------------------class TapboxA extends StatefulWidget {TapboxA({Key key}) : super(key: key);@override_TapboxAState createState() => _TapboxAState(); }class _TapboxAState extends State<TapboxA> {bool _active = false;void _handleTap() {setState(() {_active = !_active;});}Widget build(BuildContext context) {return GestureDetector(onTap: _handleTap,child: Container(child: Center(child: Text(_active ? 'Active' : 'Inactive',style: TextStyle(fontSize: 32.0, color: Colors.white),),),width: 200.0,height: 200.0,decoration: BoxDecoration(color: _active ? Colors.lightGreen[700] : Colors.grey[600],),),);} }
由Widget自身进行状态管理非常简单,由TapboxA的状态类进行状态管理。使用 _active
来决定当前值与颜色并且使用 _handleTap
来改变其值。
由父Widget进行管理
//------------------------ ParentWidget --------------------------------class ParentWidget extends StatefulWidget {@override_ParentWidgetState createState() => _ParentWidgetState(); }class _ParentWidgetState extends State<ParentWidget> {bool _active = false;void _handleTapboxChanged(bool newValue) {setState(() {_active = newValue;});}@overrideWidget build(BuildContext context) {return Container(child: TapboxB(active: _active,onChanged: _handleTapboxChanged,),);} }//------------------------- TapboxB ----------------------------------class TapboxB extends StatelessWidget {TapboxB({Key key, this.active: false, @required this.onChanged}): super(key: key);final bool active;final ValueChanged<bool> onChanged;void _handleTap() {onChanged(!active);}Widget build(BuildContext context) {return GestureDetector(onTap: _handleTap,child: Container(child: Center(child: Text(active ? 'Active' : 'Inactive',style: TextStyle(fontSize: 32.0, color: Colors.white),),),width: 200.0,height: 200.0,decoration: BoxDecoration(color: active ? Colors.lightGreen[700] : Colors.grey[600],),),);} }
由父Widget进行管理主要有:
_active _handleTapboxChanged()
而子Widget主要的特点则是:
StatelessWidget
由Widget自身及父Widget混合进行管理
//---------------------------- ParentWidget ----------------------------class ParentWidget extends StatefulWidget {@override_ParentWidgetState createState() => _ParentWidgetState(); }class _ParentWidgetState extends State<ParentWidget> {bool _active = false;void _handleTapboxChanged(bool newValue) {setState(() {_active = newValue;});}@overrideWidget build(BuildContext context) {return Container(child: TapboxC(active: _active,onChanged: _handleTapboxChanged,),);} }//----------------------------- TapboxC ------------------------------class TapboxC extends StatefulWidget {TapboxC({Key key, this.active: false, @required this.onChanged}): super(key: key);final bool active;final ValueChanged<bool> onChanged;_TapboxCState createState() => _TapboxCState(); }class _TapboxCState extends State<TapboxC> {bool _highlight = false;void _handleTapDown(TapDownDetails details) {setState(() {_highlight = true;});}void _handleTapUp(TapUpDetails details) {setState(() {_highlight = false;});}void _handleTapCancel() {setState(() {_highlight = false;});}void _handleTap() {widget.onChanged(!widget.active);}Widget build(BuildContext context) {// This example adds a green border on tap down.// On tap up, the square changes to the opposite state.return GestureDetector(onTapDown: _handleTapDown, // Handle the tap events in the order thatonTapUp: _handleTapUp, // they occur: down, up, tap, cancelonTap: _handleTap,onTapCancel: _handleTapCancel,child: Container(child: Center(child: Text(widget.active ? 'Active' : 'Inactive',style: TextStyle(fontSize: 32.0, color: Colors.white)),),width: 200.0,height: 200.0,decoration: BoxDecoration(color:widget.active ? Colors.lightGreen[700] : Colors.grey[600],border: _highlight? Border.all(color: Colors.teal[700],width: 10.0,): null,),),);} }
可以看到这种模式只是将前两种模式进行结合。在示例中,通过 _highlight
增加了在Tapbox边缘增加边框的状态,该状态由Widget自身进行管理,而 _active
状态则由父Widget进行管理。
状态管理方式的选择
状态管理方式的选择总的来说通过以下方式:
- 如果所讨论的状态是用户数据,例如复选框的选中或未选中模式,或滑块的位置,则最好由父Widget来管理状态。
- 如果所讨论的状态是动画等状态,则最好由Widget本身来管理状态。