You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何监听Boolean变量变化,在其为true时执行操作

解决Flutter异步API异常后显示错误提示的方案

基础方案:StatefulWidget + setState

这是无需额外依赖的直接实现方式:

  1. 定义状态变量:在State类中声明hasError布尔变量,初始值设为false,再加一个_hasShownError标记避免重复提示。
  2. 处理API调用:在异步方法的catch块里,通过setState将hasError更新为true。
  3. 响应状态变化:利用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为例)

如果应用状态逻辑复杂,用状态管理库可统一管理错误状态,减少重复代码:

  1. 定义全局错误状态Provider:
final errorStateProvider = StateProvider<bool>((ref) => false);
  1. 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;
  }
}
  1. 监听状态变化触发提示:
    在页面中用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 18:48:24