Ados

a fullstack game worker

0%

每天进步一点点025 - Flutter状态管理之ChangeNotifier

Preface

在所有的 app 前端中,我们基本上都会把 app 状态到变动反馈到 ui 上来。例如,服务器数据推送, locale 变更,主题变更等。此文在于学习在 flutter 中如何监听数据或者状态变动,然后将他们实时更新到 ui 上。

Contents

flutter.foundation.ChangeNotifier

ChangeNotifier 实现的是 flutter.foundation.Listenable ,它就是一个操作监听器的接口而已。监听器是用来通知客户端某对象已经更新过的。就包含两个需要实现的方法:

1
2
void addListener(VoidCallback listener);
void removeListener(VoidCallback listener);

这个是ChangeNotifier最主要的成员变量

1
2
3
4
5
List<VoidCallback?> _listeners = List<VoidCallback?>.filled(0, null);
@protected
@visibleForTesting
@pragma('vm:notify-debugger-on-exception')
void notifyListeners()

其实和 jsapi 非常像。 addListener 对应 addEventListener ,removeListener 对应 removeEventListener , notifyListeners 对应dispatchEvent

以下示范一下将 hello world 应用改为使用 ChangeNotifier

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import 'package:flutter/material.dart';

class Counter extends ChangeNotifier {
int _count = 0;
int get count => _count;

addCount() {
_count++;
notifyListeners();
}
}

class ChangeNotifierPage extends StatefulWidget {
const ChangeNotifierPage({Key? key, required this.title}) : super(key: key);

final String title;

@override
State<ChangeNotifierPage> createState() => _ChangeNotifierPageState();
}

class _ChangeNotifierPageState extends State<ChangeNotifierPage> {
Counter _counter = Counter();
@override
void initState() {
super.initState();
_counter.addListener(() {
setState(() {});
if (kDebugMode) {
print("counter value:${_counter.count}");
}
});
}

@override
void dispose() {
super.dispose();
_counter.dispose();
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'${_counter.count}',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_counter.addCount();
},
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}

ChangeNotifier 的实现比较简单,据说效率不是很好,一个项目最多使用1-2个,导致它不能在中,大型应用中使用。

Problems

extends,with,implements关键字的作用和区别

  1. extends : 继承,和 java 没啥区别,就是继承的意思,可以直接调用父类的方法,可以重写父类的方法
  2. with : 混入,其实就是复用 mixin ,可以直接调用 mixin 的方法,与 mixin 其实不是父子类的关系
  3. implements : 实现,在其他语言里就是实现某某接口的关键字, dart 里面没有接口interface 这个关键字,所以直接实现 class 里面的方法

Reference

  1. getx/doc/state_management