Flutter 颤振:在生成过程中调用serState()或markNeedBuild()

Flutter 颤振:在生成过程中调用serState()或markNeedBuild(),flutter,listview,dart,builder,consumer,Flutter,Listview,Dart,Builder,Consumer,我有一个用于选择日期的小部件,开始时是“未选择日期”,下面一列中的小部件取决于它[这意味着如果我选择了日期,它将显示一个数据时隙列表] 但是我在生成错误期间调用了一个setState,并且这个ReservationSlotWidget不能被标记为需要生成,因为框架已经在生成小部件的过程中了 这是selectDate小部件 child:Column( mainAxisAlignment:mainAxisAlignment.center, 儿童:[ 划船( mainAxisAlignment

我有一个用于选择日期的小部件,开始时是“未选择日期”,下面一列中的小部件取决于它[这意味着如果我选择了日期,它将显示一个数据时隙列表]

  • 但是我在生成错误期间调用了一个setState,并且这个ReservationSlotWidget不能被标记为需要生成,因为框架已经在生成小部件的过程中了

  • 这是selectDate小部件

  • child:Column(
    mainAxisAlignment:mainAxisAlignment.center,
    儿童:[
    划船(
    mainAxisAlignment:mainAxisAlignment.spaceBetween,
    儿童:[
    划船(
    儿童:[
    图标(
    Icons.date\u范围,
    颜色:颜色,白色,
    ),
    大小盒子(
    宽度:5,
    ),
    正文(
    _格式化==null
    “未选择日期”
    :_格式,
    样式:TextStyle(
    颜色:颜色,白色,
    ))
    ],
    ),
    扁平按钮(
    按下时:()=>\u选择ReservationDate(上下文),
    子:文本(
    “选择日期”,
    样式:TextStyle(
    颜色:颜色,白色,
    装饰:文本装饰。下划线),
    ),
    )
    ],
    ),
    如果(_selectedDate!=null)
    分隔器(
    颜色:parseColor(“#2A2E43”),
    厚度:2.0,
    ),
    如果(_selectedDate!=null)
    划船(
    儿童:[
    图标(
    图标。警报,
    颜色:颜色,白色,
    ),
    大小盒子(
    宽度:5,
    ),
    文本(“$\u numberOfSeats可用时间段”,
    样式:TextStyle(
    颜色:颜色,白色,
    ))
    ],
    ),
    
    • 这是一个列表视图,显示的项目取决于我选择的日期
    
    如果(_格式化!=null)
    扩大(
    儿童:消费者(
    建造商:(ctx,slotProvider,)=>
    ListView.builder(
    itemCount:slotProvider.slots.length,
    滚动方向:轴水平,
    itemBuilder:(ctx,索引){
    设置状态(){
    _numberOfSeats=slotProvider.slots[index].seats;
    });
    返回手势检测器(
    onTap:(){
    设置状态(){
    如果(_isInit){
    _isExpanded=!\u isExpanded;
    }
    _expandedIndex=指数;
    _isInit=假;
    });
    },
    子:容器(
    填充:边缘设置。全部(4),
    保证金:所有(4),
    装饰:盒子装饰(
    颜色:_expandedIndex==索引
    主题(上下文)原色
    :parseColor(“#2A2E43”),
    边界半径:
    边界半径所有(半径圆形(10)),
    子:SlotsWidget(
    fromTime:slotProvider.slots[index]。fromTime.toString(),
    toTime:slotProvider.slots[index].toTime.toString(),
    seats:slotProvider.slots[index]。seats,
    ))
    );
    }
    ),
    )
    ),
    
    的注释正确,您可以避免使用if块重复设置状态

    if (_numberOfSeats != slotProvider.slots[index].seats)
       setState(() {
          _numberOfSeats = slotProvider.slots[index].seats;
       });
    

    ListView
    itemBuilder
    中调用
    setState((){})
    是导致错误的原因。但是更改的座位数取决于日期和我选择的时隙索引[\u numberOfSeats=slotProvider.slots[index].seats;]
    
                  if(_formatted != null)
             
      Expanded(
                      child: Consumer<SlotProvider>(
                        builder: (ctx, slotProvider, _)=>
                         ListView.builder(
                    itemCount: slotProvider.slots.length,
                    scrollDirection: Axis.horizontal,
                    itemBuilder: (ctx, index) {
                        setState(() {
                          _numberOfSeats = slotProvider.slots[index].seats;
                        });
                        return GestureDetector(
                          onTap: () {
                            setState(() {
                              if(_isInit){
                              _isExpanded = !_isExpanded;
                              }
                               _expandedIndex = index;
                              _isInit = false;
                            });
                          },
                          child: Container(
                              padding: EdgeInsets.all(4),
                              margin: EdgeInsets.all(4),
                              decoration: BoxDecoration(
                                  color: _expandedIndex == index
                                      ? Theme.of(context).primaryColor
                                      : parseColor('#2A2E43'),
                                  borderRadius:
                                      BorderRadius.all(Radius.circular(10))),
                              child: SlotsWidget(
                                fromTime: slotProvider.slots[index].fromTime.toString(),
                                toTime:slotProvider.slots[index].toTime.toString(),
                                seats:slotProvider.slots[index].seats,
                              ))
                              );
                              }
                  ),
                      )
                  ),
                
    
    
    if (_numberOfSeats != slotProvider.slots[index].seats)
       setState(() {
          _numberOfSeats = slotProvider.slots[index].seats;
       });