Flutter小白實操之Widgets狀態(tài)管理

以下內(nèi)容參考《Flutter中文開發(fā)者社區(qū)》和《Flutter實戰(zhàn)·第二版》,僅為個人學習、熟悉Flutter,不同版本可能有稍微不一樣。

環(huán)境

///
/// 例子來源:
/// Widgets 介紹:https://flutter.cn/docs/development/ui/widgets-intro
/// 《Flutter實戰(zhàn)·第二版》:https://book.flutterchina.club/chapter2/state_manage.html
///
/// 環(huán)境:
/// 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
///

管理狀態(tài)的最常見的方法:

  • Widget 管理自己的狀態(tài)。
  • Widget 管理子 Widget 狀態(tài)。
  • 混合管理(父 Widget 和子 Widget 都管理狀態(tài))。

如何決定使用哪種管理方法?下面是官方給出的一些原則可以幫助你做決定:

  • 如果狀態(tài)是用戶數(shù)據(jù),如復選框的選中狀態(tài)、滑塊的位置,則該狀態(tài)最好由父 Widget 管理。
  • 如果狀態(tài)是有關界面外觀效果的,例如顏色、動畫,那么狀態(tài)最好由 Widget 本身來管理。
  • 如果某一個狀態(tài)是不同 Widget 共享的則最好由它們共同的父 Widget 管理。

Widget 管理自己的狀態(tài)

/// TapBoxA 管理自身狀態(tài).
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 狀態(tài)。

/// ParentWidget 為 TapBoxB 管理狀態(tài).
/// ------------------------ 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的狀態(tài)"),
        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 狀態(tài)

混合狀態(tài)管理

/// ------------------------ 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("混合狀態(tài)管理", 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),
            ),
          ),
        ),
      ),
    );
  }
}
混合狀態(tài)管理
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容