You need to enable JavaScript to run this app. Flutter:如何等待ChangeNotifier构造初始化完成后渲染ListView
优惠活动
大模型
产品
解决方案
定价
更多

Flutter:如何等待ChangeNotifier构造初始化完成后渲染ListView

问题核心原因

原来的代码存在两个会直接导致功能失效的逻辑漏洞:

  • 初始空值无防护:altitudes声明时没有设置初始值,构造函数内触发的_initialise是异步执行的任务,页面首次渲染时该值仍为null,直接访问.length属性会触发空指针异常
  • 状态变更无通知:_initialise拿到异步加载的列表完成赋值后,没有调用状态通知方法,就算数据加载完成,绑定了该状态的UI也不会触发重建重新渲染
  • 额外注意:Dart中的构造函数是同步执行的,不会等待内部触发的异步任务完成再返回,不存在“等列表加载完再走渲染逻辑”的默认等待机制
分步修复方案

1. 改造Notifier状态逻辑

需要从三个维度调整Notifier的实现:

  • 给altitudes设置初始空列表,从根源避免空指针
  • 新增加载状态标记,用来区分不同渲染阶段
  • 数据更新、状态切换时主动调用notifyListeners()通知绑定的UI层重建

调整后的Notifier代码:

class TablesNotifier with ChangeNotifier {
  final jsonSelectorService = locator<JsonSelectorService>();

  // 初始化为空列表,避免首次渲染空指针
  List<AltitudeModel> altitudes = [];
  // 新增加载状态标记
  bool isLoading = false;

  TablesNotifier(){
    _initialise();
  }

  Future _initialise() async{
    // 标记为加载中,通知UI展示加载态
    isLoading = true;
    notifyListeners();

    // 执行异步列表加载
    altitudes = await jsonSelectorService.altitudes();

    // 加载完成,切换状态并通知UI更新列表
    isLoading = false;
    notifyListeners();
  }
}

2. 改造页面渲染分支

不要在页面首次build时直接渲染列表,要根据当前Notifier的状态做分支判断,匹配对应阶段的UI:

  • 加载状态时展示居中的加载指示器,避免白屏或者崩溃
  • 空列表时展示友好的空态提示
  • 列表有数据时再正常渲染ListView.builder

调整后的页面构建逻辑:

Widget _buildBody(BuildContext context) {
  final tableProvider = Provider.of<TablesNotifier>(context);

  // 加载中分支
  if (tableProvider.isLoading) {
    return const Center(child: CircularProgressIndicator());
  }

  // 空列表分支
  if (tableProvider.altitudes.isEmpty) {
    return const Center(child: Text('暂无海拔数据'));
  }

  // 正常列表渲染分支
  return ListView.builder(
    itemCount: tableProvider.altitudes.length,
    itemBuilder: (context, index) {
      final altitudeItem = tableProvider.altitudes[index];
      return ListTile(
        title: Text('$altitudeItem'),
      );
    },
  );
}

补充说明:如果后续需要处理加载失败的场景,只需要在Notifier中新增错误信息的状态标记,在页面渲染时增加错误态的分支处理即可,整体逻辑框架和上述实现保持一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.11 11:36:04