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

Flutter页面初始化调用进度条报错,求数据加载时进度条的正确实现

Flutter 页面加载进度条报错修复与功能实现

错误原因

你遇到的报错核心是:在initState()执行期间调用了showDialog,此时Widget尚未完成挂载,无法正确访问showDialog依赖的MaterialLocalizations等InheritedWidget。initState是Widget初始化的早期阶段,上下文还没完全绑定到Widget树,直接调用依赖上下文的组件会触发这个异常。

修复方案与优化

1. 延迟执行数据加载逻辑

使用WidgetsBinding.instance.addPostFrameCallback,在Widget第一次构建完成后再启动数据加载和进度条,此时上下文已完全就绪。

2. 确保进度条必关

用try-finally包裹数据加载逻辑,避免因异常导致进度条一直显示。

3. 优化数据获取效率

原代码循环中多次串行await数据库请求,效率极低,建议改成批量请求或并行处理(可选但推荐)。

修改后的完整代码

Future<void> getUserData() async {
  // 显示进度条
  showDialog(
    context: context,
    barrierDismissible: false,
    builder: (BuildContext context) {
      return ProgressBar(
        message: "Loading..",
      );
    },
  );

  try {
    int count = await UserModel().getUsersCount();
    int userID = 101;

    // 优化:并行获取用户数据,提升加载速度
    final List<Future<List<String>>> userDataFutures = [];
    for (int i = 0; i < count - 1; i++, userID++) {
      userDataFutures.add(Future.wait([
        UserModel().getUserData(userID.toString(), 'email'),
        UserModel().getUserData(userID.toString(), 'name'),
      ]).then((values) => [userID.toString(), values[0]!, values[1]!]));
    }

    final userDataList = await Future.wait(userDataFutures);
    
    // 组装数据行
    final List<DataRow> dataRows = userDataList.map((data) {
      return DataRow(
        cells: [
          DataCell(Text(
            data[0],
            textAlign: TextAlign.right,
            style: const TextStyle(
              fontSize: 15,
              fontWeight: FontWeight.normal,
            ),
          )),
          DataCell(Text(
            data[1],
            textAlign: TextAlign.left,
            style: const TextStyle(
              fontSize: 15,
              fontWeight: FontWeight.normal,
            ),
          )),
          DataCell(Text(
            data[2],
            textAlign: TextAlign.left,
            style: const TextStyle(
              fontSize: 15,
              fontWeight: FontWeight.normal,
            ),
          )),
        ],
      );
    }).toList();

    setState(() {
      rows = dataRows;
    });
  } finally {
    // 无论成功还是失败,都关闭进度条
    Navigator.of(context, rootNavigator: true).pop();
  }
}

@override
void initState() {
  super.initState();
  // 等待Widget第一次构建完成后再执行
  WidgetsBinding.instance.addPostFrameCallback((_) {
    getUserData();
  });
}

关键修改说明

  • 延迟执行:通过addPostFrameCallback确保在Widget完成第一次绘制后启动加载,避免上下文未就绪的问题。
  • 异常安全:try-finally保证进度条一定会关闭,不会出现弹窗卡死的情况。
  • 性能优化:用Future.wait并行处理用户数据请求,替代原有的串行循环,大幅减少加载时间。

内容的提问来源于stack exchange,提问作者Mr Fin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 15:05:16