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()
|
其实和 js 的 api 非常像。 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关键字的作用和区别
- extends : 继承,和 java 没啥区别,就是继承的意思,可以直接调用父类的方法,可以重写父类的方法
- with : 混入,其实就是复用 mixin ,可以直接调用 mixin 的方法,与 mixin 其实不是父子类的关系
- implements : 实现,在其他语言里就是实现某某接口的关键字, dart 里面没有接口interface 这个关键字,所以直接实现 class 里面的方法
Reference
- getx/doc/state_management