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

Flutter中List长度始终为0?跨类构建GridView遇异常

问题根源与解决方案

核心问题:实例不共享

你每次调用AppValues()都会创建一个全新的类实例,你给这个临时实例的list_Note添加元素,但打印的也是这个新实例的列表长度——它本来就是空的,所以输出始终是0。你操作的从来不是同一个列表实例。

解决办法

方法1:将AppValues改为单例模式(推荐)

确保全局只有一个AppValues实例,所有操作都针对同一个列表:

class AppValues {
  // 私有构造函数,禁止外部直接创建实例
  AppValues._private();
  // 全局唯一实例
  static final AppValues instance = AppValues._private();

  int Grid_Row = 15;
  int NoteSepreated = 1;
  int NoteLength = 50;
  NScript SelectScript = NScript.none;

  double PlaySpeed = 1.0;
  double PlaySpeed_Default = 1.0;
  double PlaySpeed_Min = 0.0;
  double PlaySpeed_Max = 2.0;

  List<Note> list_Note = List.empty(growable: true);
}

之后修改GridView中的调用代码:

// 添加元素
AppValues.instance.list_Note.add(inst);
// 打印长度
print("Length : " + AppValues.instance.list_Note.length.toString());

方法2:手动传递同一个实例

如果不想用单例,可以在父组件中创建唯一的AppValues实例,通过参数传递给所有需要的子组件:
比如在页面的State类中声明:

final AppValues appValues = AppValues();

然后在GridView中使用这个实例:

appValues.list_Note.add(inst);
print("Length : " + appValues.list_Note.length.toString());

额外重要提醒

绝对不要在itemBuilder中添加元素到列表!itemBuilder会被Flutter频繁调用(滚动、UI重建时都会触发),这会导致你的列表被重复添加大量重复元素,数据彻底混乱。

正确做法是提前在初始化阶段构建数据,比如在页面的initState中:

@override
void initState() {
  super.initState();
  // 一次性构建所有Note数据
  for (int sec_index = 0; sec_index < iLength; sec_index++) {
    for (int sep_index = 0; sep_index < iSep; sep_index++) {
      int index1 = sec_index + 1;
      int index2 = sep_index + 1;
      var inst = Note(Sec: index1, Sep: index2);
      AppValues.instance.list_Note.add(inst);
    }
  }
  print("总长度:${AppValues.instance.list_Note.length}");
}

之后在itemBuilder中直接从列表取数据返回即可。

另外,你的问题和setState无关——setState是用来触发UI重建的,你当前的问题本质是实例不共享导致的列表操作无效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 10:25:09