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

Flutter中FutureBuilder更新时未显示进度条问题如何解决?

问题原因

出现该现象的核心原因是FutureBuilder的默认行为:当传入的Future更新时,旧数据会一直保留在snapshot.data中直到新Future执行完成。如果你优先判断snapshot.hasData再处理加载逻辑,就会始终展示旧数据。

解决方案

下面提供两种常用实现方式:

方案1:手动维护加载状态(灵活度更高,适合复杂场景)

不需要完全依赖FutureBuilder的内置状态,自己维护数据和加载标识即可:

class _MyWidgetState extends State<MyWidget> {
  List<String>? _serverData;
  bool _isLoading = false;

  // 拉取服务端数据的方法
  Future<void> _fetchData() async {
    // 开始拉取前标记为加载中
    setState(() => _isLoading = true);
    try {
      // 替换为你的实际服务端请求逻辑
      final response = await Future.delayed(const Duration(seconds: 2), () => ['数据1', '数据2', '数据3']);
      setState(() => _serverData = response);
    } catch (err) {
      // 按需添加异常处理逻辑
    } finally {
      // 无论请求成功失败,结束后关闭加载状态
      setState(() => _isLoading = false);
    }
  }

  @override
  void initState() {
    super.initState();
    // 首次进入页面加载数据
    _fetchData();
  }

  @override
  Widget build(BuildContext context) {
    // 优先判断加载状态,只要是加载中就展示进度条
    if (_isLoading) {
      return const Center(child: CircularProgressIndicator());
    }
    // 无数据展示缺省
    if (_serverData == null) {
      return const Center(child: Text('暂无数据'));
    }
    // 正常展示数据
    return Column(
      children: [
        ElevatedButton(
          onPressed: _fetchData,
          child: const Text('点击刷新数据'),
        ),
        ..._serverData!.map((item) => ListTile(title: Text(item))).toList()
      ],
    );
  }
}

方案2:调整FutureBuilder判断顺序(轻量实现,适合简单场景)

如果你不想额外维护状态,只要调整FutureBuilder的判断顺序,优先判断connectionState是否为等待状态即可:

class _MyWidgetState extends State<MyWidget> {
  Future<List<String>>? _futureData;

  // 实际的服务端请求逻辑
  Future<List<String>> _fetchRemoteData() async {
    return await Future.delayed(const Duration(seconds: 2), () => ['新数据1', '新数据2', '新数据3']);
  }

  @override
  void initState() {
    super.initState();
    _futureData = _fetchRemoteData();
  }

  // 刷新时更新Future
  void _handleRefresh() {
    setState(() {
      _futureData = _fetchRemoteData();
    });
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<List<String>>(
      future: _futureData,
      builder: (context, snapshot) {
        // 优先判断是否处于加载中,只要是等待状态就展示进度条
        if (snapshot.connectionState == ConnectionState.waiting) {
          return const Center(child: CircularProgressIndicator());
        }
        if (snapshot.hasError) {
          return Center(child: Text('加载失败:${snapshot.error}'));
        }
        if (!snapshot.hasData) {
          return const Center(child: Text('暂无数据'));
        }
        final data = snapshot.data!;
        return Column(
          children: [
            ElevatedButton(onPressed: _handleRefresh, child: const Text('点击刷新')),
            ...data.map((item) => ListTile(title: Text(item))).toList()
          ],
        );
      },
    );
  }
}

内容的提问来源于stack exchange,提问作者Manish Raj Yadav

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 10:57:01