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

Flutter问题:对象列表填充过晚引发CardSwiper断言错误

问题根源

组件构建时,readFile()异步加载数据还没完成,ExampleCandidateModel.candidates是空列表,导致cards列表为空,CardSwiper因为没有卡片触发断言错误。虽然后续数据加载完成,但静态列表更新不会触发组件重建,页面依然报错。

解决方案

方案1:将卡片列表改为组件状态变量,异步加载后触发重建

  1. 在组件状态类中定义卡片列表的状态变量,替代原来直接映射静态列表的写法。
  2. 异步加载数据完成后,通过setState()更新状态,触发组件重建,让CardSwiper拿到有效数据。

修改后代码示例:

class _ExamplePageState extends State<ExamplePage> {
  List<ExampleCard> _cards = [];

  @override
  void initState() {
    super.initState();
    _loadCards(); // 调用异步加载方法
  }

  Future<void> _loadCards() async {
    final data = await rootBundle.loadString('assets/qa_list.txt');
    final lines = const LineSplitter().convert(data);
    List<ExampleCandidateModel> candidates = [];

    for (final line in lines) {
      final words = line.split('*');
      final q = ExampleCandidateModel(
        index: int.parse(words[0].trim()),
        message: words[1].trim(),
        color: getColors(words[2].trim()),
      );
      candidates.add(q);
    }

    // 更新状态,触发组件重建
    setState(() {
      _cards = candidates.map((candidate) => ExampleCard(candidate)).toList();
    });
  }

  @override
  Widget build(BuildContext context) {
    // 数据未加载完成时显示加载状态
    if (_cards.isEmpty) {
      return const Center(child: CircularProgressIndicator());
    }

    return CardSwiper(
      cards: _cards,
      // 其他配置参数
    );
  }
}

方案2:使用FutureBuilder处理异步加载

直接在build方法中用FutureBuilder管理异步加载状态,无需手动调用setState():

class _ExamplePageState extends State<ExamplePage> {
  Future<List<ExampleCard>> _fetchCards() async {
    final data = await rootBundle.loadString('assets/qa_list.txt');
    final lines = const LineSplitter().convert(data);
    List<ExampleCandidateModel> candidates = [];

    for (final line in lines) {
      final words = line.split('*');
      final q = ExampleCandidateModel(
        index: int.parse(words[0].trim()),
        message: words[1].trim(),
        color: getColors(words[2].trim()),
      );
      candidates.add(q);
    }

    return candidates.map((candidate) => ExampleCard(candidate)).toList();
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<List<ExampleCard>>(
      future: _fetchCards(),
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return const Center(child: CircularProgressIndicator());
        } else if (snapshot.hasError) {
          return Center(child: Text('加载失败: ${snapshot.error}'));
        } else if (!snapshot.hasData || snapshot.data!.isEmpty) {
          return const Center(child: Text('暂无卡片数据'));
        }

        return CardSwiper(
          cards: snapshot.data!,
          // 其他配置参数
        );
      },
    );
  }
}
注意事项
  • 避免用静态列表存储需要动态加载的组件数据,静态变量无法触发组件状态更新,会导致UI和数据不同步。
  • 必须在数据加载完成前给CardSwiper提供非空列表,或者显示加载/空状态,避免触发断言错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 00:28:31