Flutter2.*_状态管理

雲海垂钓

共 3097字,需浏览 7分钟

 · 2021-11-01

    Flutter以widget作为的基础,分为有状态和无状态两类,可以简单以是否存在交互为判断依据,不存在则为无状态组件Statelesswige,否则即有状态组件StatefulWidget,二者皆继承与父类Widget。今天我们来聊一下有状态组件的状态管理。


    flutter有多种办法管理状态,作为开发者,需要定义管理的方法,如果眼下对于此中的规则不清楚,可以默认在父类widget中管理状态。细致来说,根据具体地开发情况,有三种思路管理状态:widget管理自己的状态、父widget管理此widget的状态、混搭管理,决定此三种选择哪一个,可以参考原则:

    · 若状态是用户数据,如复选框选中、滑块位置,状态由父widget管理;

    ·若所讨论的状态与界面外观,则widget本身管理状态;


自身管理状态:

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Flutter Demo'),
        ),
        body: const Center(
          child: TapboxA(),
        ),
      ),
    );
  }}


class TapboxA extends StatefulWidget {
  const TapboxA({Key? key}) : super(key: key);

  @override
  _TapboxAState createState() => _TapboxAState();}class _TapboxAState extends State {
  bool _active = false;

  void _handleTap() {
    setState(() {
      _active = !_active;
    });
  }

  @override  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: _handleTap,
      child: Container(
        child: Center(
          child: Text(
            _active ? 'Active' : 'Inactive',
            style: const TextStyle(fontSize: 32.0, color: Colors.white),
          ),
        ),
        width: 200.0,
        height: 200.0,
        decoration: BoxDecoration(
          color: _active ? Colors.lightGreen[700] : Colors.grey[600],
        ),
      ),
    );
  }}



父widget管理widget状态,此种场景一般用在当前组件是无状态的,需要父类widget来进行识别作为子组件的目标是否要执行不同条件对应的逻辑,来看下列示例代码:

class TapboxB extends StatelessWidget {
  const TapboxB({
    Key? key,
    this.active = false,
    required this.onChanged,
  }) : super(key: key);

  final bool active;
  final ValueChanged onChanged;

  void _handleTap() {
    onChanged(!active);
  }

  @override  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: _handleTap,
      child: Container(
        child: Center(
          child: Text(
            active ? 'Active' : 'Inactive',
            style: const TextStyle(fontSize: 32.0, color: Colors.white),
          ),
        ),
        width: 200.0,
        height: 200.0,
        decoration: BoxDecoration(
          color: active ? Colors.lightGreen[700] : Colors.grey[600],
        ),
      ),
    );
  }}

作为子组件的TapboxB为无状态组件,在接收点击事件通过onChanged通知父组件 ParentWidget,ParentWidget以_handleTapboxChanged接收的value更新设置TapboxB属性_active,同时更新widget树渲染页面。

class ParentWidget extends StatefulWidget {
  const ParentWidget({Key? key}) : super(key: key);

  @override
  _ParentWidgetState createState() => _ParentWidgetState();}class _ParentWidgetState extends State {
  bool _active = false;

  void _handleTapboxChanged(bool newValue) {
    setState(() {
      _active = newValue;
    });
  }

  @override  Widget build(BuildContext context) {
    return SizedBox(
      child: TapboxB(
        active: _active,
        onChanged: _handleTapboxChanged,
      ),
    );
  }}



    混合管理即为组件自管理和父类组件管理子组件状态的组合使用,flutter提供各种按钮和类似的交互式widget,可以参考material design gudelines.

    感谢各位抽出时间阅读,如果各位对此有新的想法和疑问,欢迎留言探讨,或者通过下面二维码进群讨论学习。

浏览 9
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报