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
相关产品推荐
相关产品推荐

