Flutter:使用ChangeNotifier创建类为何需关键词?实例为何需getter/listen:false?
Flutter Provider 两个常见疑问解答
1. 创建ChangeNotifier子类时,为啥要调用notifyListeners()?
(注:推测你说的“获取关键词”是表述误差,实际指调用notifyListeners()方法)
ChangeNotifier的核心作用就是管理状态通知——你在子类里修改了状态(比如计数器加1、用户信息更新),如果不调用notifyListeners(),Provider根本感知不到状态变化,自然不会通知依赖的UI组件刷新,界面就会停留在旧状态。
举个实际例子:
class Counter extends ChangeNotifier { int _count = 0; int get count => _count; void addOne() { _count++; // 必须加这一行,不然点击按钮数字不会更新 notifyListeners(); } }
说白了,notifyListeners()就是给Provider发信号:“我状态变了,赶紧让相关UI更新一下”。
2. 在类里获取ChangeNotifier实例时,为啥必须用getter或者把listen设为false,不然会报错?
这里说的“类里”大多指StatefulWidget的State类(比如initState、didUpdateWidget这些生命周期方法中):
默认情况下Provider.of<T>(context)的listen参数是true,意思是会订阅状态变化,状态一变就触发当前组件重建。但Flutter不允许在非build的生命周期方法里添加这种监听——这些方法是用来做初始化、更新前准备的,不是处理UI重建的,硬加监听会打乱生命周期逻辑,所以直接调用就会报错。
解决办法有两种:
- 把
listen设为false:只获取实例,不订阅状态变化,适合只需要调用实例方法(比如触发状态修改)、不需要监听更新的场景:@override void initState() { super.initState(); final counter = Provider.of<Counter>(context, listen: false); counter.addOne(); // 仅调用方法,不监听状态变化 } - 用getter封装:在State类里写个getter,需要的时候再获取实例,本质也是避免在生命周期阶段提前订阅:
Counter get counter => Provider.of<Counter>(context, listen: false); @override void didUpdateWidget(oldWidget) { super.didUpdateWidget(oldWidget); counter.addOne(); }
注意:如果是在build方法里,直接用Provider.of<T>(context)(默认listen: true)完全没问题,因为build本身就是用来构建UI的,状态变化时重建是合理逻辑。
内容的提问来源于stack exchange,提问作者Technical Secrets
相关产品推荐
相关产品推荐

