Flutter中如何监听Boolean变量变化,在其为true时执行操作
解决Flutter异步API异常后显示错误提示的方案
基础方案:StatefulWidget + setState
这是无需额外依赖的直接实现方式:
- 定义状态变量:在State类中声明
hasError布尔变量,初始值设为false,再加一个_hasShownError标记避免重复提示。 - 处理API调用:在异步方法的
catch块里,通过setState将hasError更新为true。 - 响应状态变化:利用
didUpdateWidget生命周期方法,在hasError变为true且未显示过提示时,触发错误提示逻辑。
示例代码:
class MyPage extends StatefulWidget { @override State<MyPage> createState() => _MyPageState(); } class _MyPageState extends State<MyPage> { bool hasError = false; bool _hasShownError = false; Future<void> fetchData() async { try { // 模拟API调用逻辑 await Future.delayed(const Duration(seconds: 2)); throw Exception("API请求失败"); } catch (e) { setState(() { hasError = true; }); } } @override void didUpdateWidget(covariant MyPage oldWidget) { super.didUpdateWidget(oldWidget); if (hasError && !_hasShownError) { _showErrorSnackBar(); _hasShownError = true; } } void _showErrorSnackBar() { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text("请求出错,请稍后重试")), ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text("示例页面")), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton( onPressed: fetchData, child: const Text("发起API请求"), ), // 也可直接在build中根据状态显示静态错误提示 if (hasError) const Padding( padding: EdgeInsets.only(top: 20), child: Text("请求出错了", style: TextStyle(color: Colors.red)), ), ], ), ), ); } }
进阶方案:状态管理库(以Riverpod为例)
如果应用状态逻辑复杂,用状态管理库可统一管理错误状态,减少重复代码:
- 定义全局错误状态Provider:
final errorStateProvider = StateProvider<bool>((ref) => false);
- API调用中更新状态:
Future<void> fetchData(WidgetRef ref) async { try { // 实际API调用逻辑 await Future.delayed(const Duration(seconds: 2)); throw Exception("API请求失败"); } catch (e) { ref.read(errorStateProvider.notifier).state = true; } }
- 监听状态变化触发提示:
在页面中用Consumer监听状态,仅当状态从false变为true时显示提示,可选显示后重置状态以便下次触发:
class MyPage extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { ref.listen<bool>(errorStateProvider, (previous, next) { if (next == true && previous == false) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text("请求出错,请稍后重试")), ); // 重置状态,方便后续错误再次触发提示 ref.read(errorStateProvider.notifier).state = false; } }); return Scaffold( appBar: AppBar(title: const Text("Riverpod示例")), body: Center( child: ElevatedButton( onPressed: () => fetchData(ref), child: const Text("发起API请求"), ), ), ); } }
关键注意事项
- 必须通过
setState或状态管理库的更新方法修改状态,否则Flutter不会重建UI响应变化。 - 加标记或重置状态是为了避免同一错误多次触发提示,提升用户体验。
- 若需全局统一处理API错误,可封装错误拦截类,在异常抛出时直接触发全局提示逻辑。
内容的提问来源于stack exchange,提问作者ASISH KUMAR
相关产品推荐
相关产品推荐

