美文网首页
Flutter小白实操之Widgets状态管理

Flutter小白实操之Widgets状态管理

作者: WeeverLu | 来源:发表于2023-05-26 20:56 被阅读0次

以下内容参考《Flutter中文开发者社区》和《Flutter实战·第二版》,仅为个人学习、熟悉Flutter,不同版本可能有稍微不一样。

环境

///
/// 例子来源:
/// Widgets 介绍:https://flutter.cn/docs/development/ui/widgets-intro
/// 《Flutter实战·第二版》:https://book.flutterchina.club/chapter2/state_manage.html
///
/// 环境:
/// Flutter 3.10.1 • channel stable • https://github.com/flutter/flutter.git
/// Framework • revision d3d8effc68 (7 days ago) • 2023-05-16 17:59:05 -0700
/// Engine • revision b4fb11214d
/// Tools • Dart 3.0.1 • DevTools 2.23.1
///

管理状态的最常见的方法:

  • Widget 管理自己的状态。
  • Widget 管理子 Widget 状态。
  • 混合管理(父 Widget 和子 Widget 都管理状态)。

如何决定使用哪种管理方法?下面是官方给出的一些原则可以帮助你做决定:

  • 如果状态是用户数据,如复选框的选中状态、滑块的位置,则该状态最好由父 Widget 管理。
  • 如果状态是有关界面外观效果的,例如颜色、动画,那么状态最好由 Widget 本身来管理。
  • 如果某一个状态是不同 Widget 共享的则最好由它们共同的父 Widget 管理。

Widget 管理自己的状态

/// TapBoxA 管理自身状态.
class TapBoxA extends StatefulWidget {
  const TapBoxA({super.key});

  @override
  State<TapBoxA> createState() => _TapBoxAState();
}

class _TapBoxAState extends State<TapBoxA> {
  bool _active = false;

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

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

Widget 管理子 Widget 状态。

/// ParentWidget 为 TapBoxB 管理状态.
/// ------------------------ ParentWidget --------------------------------
class ParentWidget extends StatefulWidget {
  const ParentWidget({super.key});

  @override
  State<ParentWidget> createState() => ParentWidgetState();
}

class ParentWidgetState extends State<ParentWidget> {
  bool _active = false;

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("父管理子Widget的状态"),
        backgroundColor: Colors.black,
      ),
      body: TapBoxB(
        active: _active,
        onChanged: handleTapBoxChange,
      ),
    );
  }
}

///------------------------ TapBoxB ----------------------------------
class TapBoxB extends StatelessWidget {
  const TapBoxB({super.key, this.active = false, required this.onChanged});

  final bool active;
  final ValueChanged<bool> onChanged;

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

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: _handleTap,
      child: Center(
        child: Container(
          width: 200.0,
          height: 200.0,
          decoration: BoxDecoration(
            color: active ? Colors.red[700] : Colors.blue[600],
          ),
          child: Center(
            child: Text(
              active ? "Active" : "Inactive",
              style: const TextStyle(fontSize: 30, color: Colors.white),
            ),
          ),
        ),
      ),
    );
  }
}
Widget 管理子 Widget 状态

混合状态管理

/// ------------------------ ParentWidgetC --------------------------------
class ParentWidgetC extends StatefulWidget {
  const ParentWidgetC({super.key});

  @override
  State<ParentWidgetC> createState() => _ParentWidgetCState();
}

class _ParentWidgetCState extends State<ParentWidgetC> {
  bool _activeState = false;

  void _handleTabBoxChange(bool newValue) {
    setState(() {
      _activeState = newValue;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("混合状态管理", style: TextStyle(color: Colors.white)),
        backgroundColor: Colors.blue[500],
      ),
      body: TapBoxC(
        active: _activeState,
        onChanged: _handleTabBoxChange,
      ),
    );
  }
}

///----------------------------- TapBoxC ------------------------------
class TapBoxC extends StatefulWidget {
  const TapBoxC({super.key, this.active = false, required this.onChanged});

  final bool active;
  final ValueChanged<bool> onChanged;

  @override
  State<TapBoxC> 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() {
    setState(() {
      widget.onChanged(!widget.active);
    });
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: handleTap,
      onTapDown: handleTapDown,
      onTapUp: handleTapUp,
      onTapCancel: handleTapCancel,
      child: Center(
        child: Container(
          width: 200.0,
          height: 200.0,
          decoration: BoxDecoration(
            color: widget.active ? Colors.pink[200] : Colors.cyan[500],
            border: highlight
                ? Border.all(color: Colors.orange[700]!, width: 10,)
                //Border(top: BorderSide(color: Colors.orange[700]!, width: 10))
                : null,
          ),
          child: Center(
            child: Text(
              widget.active ? "Active" : "Inactive",
              style: const TextStyle(fontSize: 30, color: Colors.white),
            ),
          ),
        ),
      ),
    );
  }
}
混合状态管理

相关文章

网友评论

      本文标题:Flutter小白实操之Widgets状态管理

      本文链接:https://www.haomeiwen.com/subject/xbxledtx.html