Flutter中Drawer内Provider值无法实时更新的问题求助
问题根源
核心问题是存在两个独立的GlobalsProvider实例:
- Main中通过
ChangeNotifierProvider创建的全局实例,是Forms页面监听的实例。 - Login页面中自行new的
globalsClass = GlobalsProvider()实例,定时器是在这个独立实例上运行的。
定时器发送数据后更新的是Login私有实例的数值,Forms页面监听的全局实例完全没收到更新通知,所以抽屉里的数字始终不变。
修复步骤
删除Login页面中独立的Provider实例
移除final globalsClass = GlobalsProvider();这行代码,不再自行创建实例。通过Context获取全局Provider实例
在Login的initialize方法中,使用context.read<GlobalsProvider>()获取全局的Provider实例,再启动定时器。注意initState中不能直接使用context,需要用WidgetsBinding.instance.addPostFrameCallback延迟执行。确保定时器操作全局实例
这样定时器发送数据后,更新的就是Forms页面监听的全局实例的pendingOutgoingTransactions,调用notifyListeners()后,Forms的Consumer会重新构建,抽屉里的数值就能正常更新。
修改后的Login代码
class Login extends StatefulWidget { const Login({super.key}); @override State<Login> createState() => _LoginState(); } class _LoginState extends State<Login> { @override void initState() { super.initState(); // 延迟到第一帧构建完成后获取context WidgetsBinding.instance.addPostFrameCallback((_) { initialize(); }); } @override void dispose() { super.dispose(); } void initialize() async { // 获取全局的GlobalsProvider实例 final globals = context.read<GlobalsProvider>(); globals.localDBStartOutgoingStream(); if (serverList.isNotEmpty) { //...你的其他逻辑 } } @override Widget build(BuildContext context) { return Consumer<GlobalsProvider>( builder: (context, globals, child) => Scaffold( appBar: //... body: //... ) ); } }
额外检查点
- 确认
localDBOutgoingStream方法中,发送数据到SQL Server后确实删除了sqflite中的对应行,否则localDBQueryRowCount返回的数值不会减少。 - 可以在
localDBOutgoingStream中添加打印日志,验证physInvRowsAfter的数值是否正确,以及notifyListeners()是否被调用。
内容的提问来源于stack exchange,提问作者TheMortiestMorty
相关产品推荐
相关产品推荐

