[关闭]
@qidiandasheng 2022-07-29T08:07:45.000000Z 字数 8578 阅读 85

Flutter状态管理

Flutter


setState

  1. import 'package:flutter/material.dart';
  2. class CounterPage extends StatefulWidget {
  3. const CounterPage({Key? key, required this.title}) : super(key: key);
  4. final String title;
  5. @override
  6. CounterPageState createState() => CounterPageState();
  7. }
  8. class CounterPageState extends State<CounterPage> {
  9. int _counter = 0;
  10. void _incrementCounter() {
  11. setState(() {
  12. _counter++;
  13. });
  14. }
  15. void _decrementCounter() {
  16. setState(() {
  17. _counter--;
  18. });
  19. }
  20. @override
  21. Widget build(BuildContext context) {
  22. return Scaffold(
  23. appBar: AppBar(
  24. title: Text(widget.title),
  25. ),
  26. body: Center(
  27. child: Counter(
  28. counter: _counter,
  29. decrementCounter: _decrementCounter,
  30. incrementCounter: _incrementCounter)));
  31. }
  32. }
  33. class Counter extends StatelessWidget {
  34. final counter;
  35. final decrementCounter;
  36. final incrementCounter;
  37. Counter(
  38. {Key? key,
  39. this.counter: 0,
  40. @required this.decrementCounter,
  41. @required this.incrementCounter})
  42. : super(key: key);
  43. @override
  44. Widget build(BuildContext context) {
  45. return Scaffold(
  46. body: Column(
  47. mainAxisAlignment: MainAxisAlignment.center,
  48. children: <Widget>[
  49. Row(
  50. mainAxisAlignment: MainAxisAlignment.center,
  51. children: [
  52. Text(
  53. 'Counter:',
  54. style: Theme.of(context).textTheme.headline4,
  55. ),
  56. Text(
  57. '$counter',
  58. style: Theme.of(context).textTheme.headline4,
  59. ),
  60. ],
  61. ),
  62. TextButton(
  63. style: ButtonStyle(
  64. backgroundColor:
  65. MaterialStateProperty.resolveWith((states) => Colors.orange)),
  66. child:
  67. Text('Increment Counter', style: TextStyle(color: Colors.white)),
  68. onPressed: incrementCounter,
  69. ),
  70. TextButton(
  71. style: ButtonStyle(
  72. backgroundColor:
  73. MaterialStateProperty.resolveWith((states) => Colors.red)),
  74. child:
  75. Text('Decrement Counter', style: TextStyle(color: Colors.white)),
  76. onPressed: decrementCounter,
  77. )
  78. ],
  79. ));
  80. }
  81. }

InheritedWidget

  1. import 'package:flutter/material.dart';
  2. class CounterPage extends StatefulWidget {
  3. const CounterPage({Key? key, required this.title}) : super(key: key);
  4. final String title;
  5. static CounterPageState of(BuildContext context) {
  6. return context
  7. .dependOnInheritedWidgetOfExactType<MyInheritedWidget>()!
  8. .data;
  9. }
  10. @override
  11. CounterPageState createState() => CounterPageState();
  12. }
  13. class CounterPageState extends State<CounterPage> {
  14. int _counter = 0;
  15. void _incrementCounter() {
  16. setState(() {
  17. _counter++;
  18. });
  19. }
  20. void _decrementCounter() {
  21. setState(() {
  22. _counter--;
  23. });
  24. }
  25. @override
  26. Widget build(BuildContext context) {
  27. return Scaffold(
  28. appBar: AppBar(
  29. title: Text(widget.title),
  30. ),
  31. body: Center(child: MyInheritedWidget(child: Counter(), data: this)));
  32. }
  33. }
  34. class Counter extends StatefulWidget {
  35. const Counter({Key? key}) : super(key: key);
  36. @override
  37. CounterState createState() => CounterState();
  38. }
  39. class CounterState extends State<Counter> {
  40. late int counter;
  41. late CounterPageState data;
  42. @override
  43. void didChangeDependencies() {
  44. super.didChangeDependencies();
  45. data = CounterPage.of(context);
  46. counter = data._counter;
  47. }
  48. @override
  49. Widget build(BuildContext context) {
  50. return Scaffold(
  51. body: Column(
  52. mainAxisAlignment: MainAxisAlignment.center,
  53. children: <Widget>[
  54. Row(
  55. mainAxisAlignment: MainAxisAlignment.center,
  56. children: [
  57. Text(
  58. 'Inherited Counter:',
  59. style: Theme.of(context).textTheme.headline4,
  60. ),
  61. Text(
  62. '$counter',
  63. style: Theme.of(context).textTheme.headline4,
  64. ),
  65. ],
  66. ),
  67. TextButton(
  68. style: ButtonStyle(
  69. backgroundColor:
  70. MaterialStateProperty.resolveWith((states) => Colors.orange)),
  71. child: const Text('Increment Counter',
  72. style: TextStyle(color: Colors.white)),
  73. onPressed: data._incrementCounter,
  74. ),
  75. TextButton(
  76. style: ButtonStyle(
  77. backgroundColor:
  78. MaterialStateProperty.resolveWith((states) => Colors.red)),
  79. child: const Text('Decrement Counter',
  80. style: TextStyle(color: Colors.white)),
  81. onPressed: data._decrementCounter,
  82. )
  83. ],
  84. ));
  85. }
  86. }
  87. class MyInheritedWidget extends InheritedWidget {
  88. final CounterPageState data;
  89. const MyInheritedWidget({
  90. Key? key,
  91. required Widget child,
  92. required this.data,
  93. }) : super(key: key, child: child);
  94. @override
  95. bool updateShouldNotify(InheritedWidget oldWidget) {
  96. return true;
  97. }
  98. }

InheritedModel

  1. import 'package:flutter/material.dart';
  2. class CounterPage extends StatefulWidget {
  3. const CounterPage({Key? key, required this.title}) : super(key: key);
  4. final String title;
  5. @override
  6. CounterPageState createState() => CounterPageState();
  7. }
  8. class CounterPageState extends State<CounterPage> {
  9. int _counter = 0;
  10. void _incrementCounter() {
  11. setState(() {
  12. _counter++;
  13. });
  14. }
  15. void _decrementCounter() {
  16. setState(() {
  17. _counter--;
  18. });
  19. }
  20. @override
  21. Widget build(BuildContext context) {
  22. return Scaffold(
  23. appBar: AppBar(
  24. title: Text(widget.title),
  25. ),
  26. body: Center(child: MyInheritedModel(child: const Counter(), data: this)));
  27. }
  28. }
  29. class Counter extends StatefulWidget {
  30. const Counter({Key? key}) : super(key: key);
  31. @override
  32. CounterState createState() => CounterState();
  33. }
  34. class CounterState extends State<Counter> {
  35. late int counter;
  36. late MyInheritedModel inheritedModel;
  37. @override
  38. Widget build(BuildContext context) {
  39. inheritedModel = MyInheritedModel.of(context);
  40. counter = inheritedModel.data._counter;
  41. return Scaffold(
  42. body: Column(
  43. mainAxisAlignment: MainAxisAlignment.center,
  44. children: <Widget>[
  45. Row(
  46. mainAxisAlignment: MainAxisAlignment.center,
  47. children: [
  48. Text(
  49. 'Inherited Counter:',
  50. style: Theme.of(context).textTheme.headline4,
  51. ),
  52. Text(
  53. '$counter',
  54. style: Theme.of(context).textTheme.headline4,
  55. ),
  56. ],
  57. ),
  58. TextButton(
  59. style: ButtonStyle(
  60. backgroundColor:
  61. MaterialStateProperty.resolveWith((states) => Colors.orange)),
  62. child: const Text('Increment Counter',
  63. style: TextStyle(color: Colors.white)),
  64. onPressed: inheritedModel.data._incrementCounter,
  65. ),
  66. TextButton(
  67. style: ButtonStyle(
  68. backgroundColor:
  69. MaterialStateProperty.resolveWith((states) => Colors.red)),
  70. child: const Text('Decrement Counter',
  71. style: TextStyle(color: Colors.white)),
  72. onPressed: inheritedModel.data._decrementCounter,
  73. )
  74. ],
  75. ));
  76. }
  77. }
  78. class MyInheritedModel extends InheritedModel<String> {
  79. final CounterPageState data;
  80. const MyInheritedModel({
  81. Key? key,
  82. required Widget child,
  83. required this.data,
  84. }) : super(key: key, child: child);
  85. @override
  86. bool updateShouldNotify(MyInheritedModel old) {
  87. return true;
  88. }
  89. @override
  90. bool updateShouldNotifyDependent(MyInheritedModel old, Set<String> aspects) {
  91. return true;
  92. }
  93. static MyInheritedModel of(BuildContext context, {String aspect = ""}) {
  94. return InheritedModel.inheritFrom<MyInheritedModel>(context,
  95. aspect: aspect)!;
  96. }
  97. }

Provider

  1. import 'package:flutter/material.dart';
  2. import 'package:provider/provider.dart';
  3. class ProCounter with ChangeNotifier {
  4. int _counter = 0;
  5. int get counter => _counter;
  6. void _incrementCounter() {
  7. _counter++;
  8. notifyListeners();
  9. }
  10. void _decrementCounter() {
  11. _counter--;
  12. notifyListeners();
  13. }
  14. }
  15. class CounterPage extends StatelessWidget {
  16. const CounterPage({Key? key, required this.title}) : super(key: key);
  17. final String title;
  18. @override
  19. Widget build(BuildContext context) {
  20. return MultiProvider(
  21. providers: [ChangeNotifierProvider(create: (_) => ProCounter())],
  22. child: Scaffold(appBar: AppBar(title: Text(title)), body: const Counter()));
  23. }
  24. }
  25. class Counter extends StatelessWidget {
  26. const Counter({Key? key}) : super(key: key);
  27. @override
  28. Widget build(BuildContext context) {
  29. final counter = Provider.of<ProCounter>(context);
  30. return Column(
  31. mainAxisAlignment: MainAxisAlignment.center,
  32. children: <Widget>[
  33. Row(
  34. mainAxisAlignment: MainAxisAlignment.center,
  35. children: [
  36. Text(
  37. 'Inherited Counter:',
  38. style: Theme.of(context).textTheme.headline4,
  39. ),
  40. Text(
  41. '${counter.counter}',
  42. style: Theme.of(context).textTheme.headline4,
  43. ),
  44. ],
  45. ),
  46. TextButton(
  47. style: ButtonStyle(
  48. backgroundColor: MaterialStateProperty.resolveWith(
  49. (states) => Colors.orange)),
  50. child: const Text('Increment Counter',
  51. style: TextStyle(color: Colors.white)),
  52. onPressed: () {
  53. Provider.of<ProCounter>(context, listen: false)
  54. ._incrementCounter();
  55. }),
  56. TextButton(
  57. style: ButtonStyle(
  58. backgroundColor:
  59. MaterialStateProperty.resolveWith((states) => Colors.red)),
  60. child: const Text('Decrement Counter',
  61. style: TextStyle(color: Colors.white)),
  62. onPressed: () {
  63. Provider.of<ProCounter>(context, listen: false)
  64. ._decrementCounter();
  65. })
  66. ],
  67. );
  68. }
  69. }

GetX

  1. import 'package:flutter/material.dart';
  2. import 'package:get/get.dart';
  3. class CounterController extends GetxController {
  4. /// (1,2)定义了该变量为响应式变量,当该变量数值变化时,页面的刷新方法将自动刷新
  5. // var counter = 0.obs;
  6. // (3)GetBuilder
  7. var counter = 0;
  8. void incrementCounter() {
  9. counter++;
  10. // (3)使用GetBuilder时手动更新
  11. update();
  12. }
  13. void decrementCounter() {
  14. counter--;
  15. update();
  16. }
  17. }
  18. class CounterPage extends StatefulWidget {
  19. const CounterPage({Key? key, required this.title}) : super(key: key);
  20. final String title;
  21. @override
  22. CounterPageState createState() => CounterPageState();
  23. }
  24. class CounterPageState extends State<CounterPage> {
  25. @override
  26. Widget build(BuildContext context) {
  27. /// 通过依赖注入方式实例化的控制器
  28. final counter = Get.put(CounterController());
  29. return Scaffold(
  30. appBar: AppBar(
  31. title: Text(widget.title),
  32. ),
  33. body: Center(
  34. child: Column(
  35. mainAxisAlignment: MainAxisAlignment.center,
  36. children: [
  37. // 1.
  38. // Obx(() => Text(
  39. // "count的值为:${counter.counter}",
  40. // style: const TextStyle(color: Colors.redAccent, fontSize: 20),
  41. // )),
  42. // 2.
  43. // GetX<CounterController>(
  44. // init: counter,
  45. // builder: (controller) {
  46. // return Text(
  47. // "count的值为:${controller.counter}",
  48. // style: const TextStyle(color: Colors.redAccent, fontSize: 20),
  49. // );
  50. // },
  51. // ),
  52. // 3.
  53. GetBuilder<CounterController>(
  54. builder: (oneController) {
  55. return Text("count的值为: ${oneController.counter}");
  56. },
  57. ),
  58. const SizedBox(
  59. height: 30,
  60. ),
  61. ElevatedButton(
  62. // 按钮点击count值++
  63. onPressed: () => counter.incrementCounter(),
  64. child: const Text("点击count++"),
  65. ),
  66. ],
  67. )));
  68. }
  69. }

参考

Flutter 状态管理概述
Flutter状态管理之路(一)
Flutter状态管理之路(二)
Flutter状态管理GetX使用详解

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注