Flutter状态管理之InheritedWidget

1.创建数据模型 CounterModel

1
class CounterModel {
2
  final int count;
3
  const CounterModel(this.count);
4
}

2.创建 InheritedWidget

1
class CounterInherited extends InheritedWidget {
2
  Widget child;
3
  final data;
4
  CounterInherited({
5
    Key key,
6
    @required this.child,
7
    @required this.data,
8
  }) : super(key: key, child: child);
9
  @override
10
  bool updateShouldNotify(CounterInherited oldWidget) {
11
    return true;
12
  }
13
}

3.用CounterInherited包装Widget树

1
class CounterInheritedWidget extends StatefulWidget {
2
  final Widget child;
3
  CounterInheritedWidget({Key key, this.child}) : super(key: key);
4
  @override
5
  CounterInheritedWidgetState createState() => CounterInheritedWidgetState();
6
  static CounterInheritedWidgetState of(BuildContext context, bool rebuild){
7
    return (rebuild ? context.dependOnInheritedWidgetOfExactType<CounterInherited>() : context.findAncestorWidgetOfExactType<CounterInherited>()).data;
8
  }
9
}
10
class CounterInheritedWidgetState extends State<CounterInheritedWidget> {
11
  CounterModel counter = CounterModel(0);
12
  int get count => counter.count;
13
  void increment(){
14
    if (count < 10) {
15
      counter = CounterModel(counter.count+1);
16
      setState(() {});
17
    }
18
  }
19
  void reduce(){
20
    counter = CounterModel(counter.count-1);
21
    setState(() {});
22
  }
23
  void cleaar(){
24
    counter = CounterModel(0);
25
    setState(() {});
26
  }
27
  @override
28
  Widget build(BuildContext context) {
29
    return CounterInherited(
30
      data: this,
31
      child: widget.child,
32
    );
33
  }
34
}

4.组件容器

1
class CounterWidget extends StatefulWidget {
2
  @override
3
  _CounterWidgetState createState() => _CounterWidgetState();
4
}
5
6
class _CounterWidgetState extends State<CounterWidget> {
7
  @override
8
  Widget build(BuildContext context) {
9
    return CounterInheritedWidget(
10
      child: Scaffold(
11
        appBar: AppBar(
12
          title: Text('InheritedWidgetDemo'),
13
          elevation: 0.0,
14
        ),
15
        body: Center(
16
          child: Column(
17
            mainAxisAlignment: MainAxisAlignment.center,
18
            children: <Widget>[
19
              IncrementWidget(),
20
              Counter(),
21
              ReduceWidget(),
22
              StatelessWidgetDemo(),
23
            ],
24
          ),
25
        ),
26
      ),
27
    );
28
  }
29
}

5.拆分组件

1
class Counter extends StatelessWidget {
2
  @override
3
  Widget build(BuildContext context) {
4
    final CounterInheritedWidgetState state = CounterInheritedWidget.of(context,true);
5
    print('Counter -- CounterModel 中的count值:${state.count}');
6
    return Container(
7
      child: ActionChip(
8
        label: Text('${state.count}'),
9
        onPressed: state.cleaar
10
      ),
11
    );
12
  }
13
}
14
15
class IncrementWidget extends StatelessWidget {
16
  @override
17
  Widget build(BuildContext context) {
18
    final CounterInheritedWidgetState state = CounterInheritedWidget.of(context,false);
19
    print('IncrementWidget ---- CounterModel 中的count值:${state.count}');
20
    return Container(
21
      child: FlatButton(
22
        onPressed: state.increment,
23
        child: Icon(Icons.add),
24
        color: Colors.blue,
25
        textColor: Colors.white,
26
      ),
27
    );
28
  }
29
}
30
31
class ReduceWidget extends StatelessWidget {
32
  @override
33
  Widget build(BuildContext context) {
34
    final CounterInheritedWidgetState state = CounterInheritedWidget.of(context,false);
35
    print('ReduceWidget  ---  CounterModel 中的count值:${state.count}');
36
    return Container(
37
      child: FlatButton(
38
        onPressed: state.reduce,
39
        child: Icon(Icons.remove),
40
        color: Colors.blue,
41
        textColor: Colors.white,
42
      ),
43
    );
44
  }
45
}
46
47
48
class StatelessWidgetDemo extends StatelessWidget {
49
  @override
50
  Widget build(BuildContext context) {
51
    print('StatelessWidgetDemo');
52
    return Container(
53
      padding: EdgeInsets.all(8.0),
54
      child: Text('无状态Widget'),
55
    );
56
  }
57
}

在这个例子中:
* CounterModel 是保存数据的模型
* CounterInherited 继承了 InheritedWidget ,每次点击按钮改变时都会重新构建它。
* 让 CounterInheritedWidget 作为 Widget 树的父级。内部定义了操作方法以及数据
* 点击 IncrementWidget 小部件时, 通过 CounterInheritedWidget.of(context,false); 获得 CounterInheritedWidgetState
实例,执行 increment 方法改变 CounterModel模型的数据。然后Counter通过CounterInheritedWidgetState更新数据.

static CounterInheritedWidgetState of(BuildContext context, bool rebuild){} 方法中,通过传递 rebuild 来控制是否重构小部件。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!