如何解决此错误“在构建期间调用setState()或markNeedsBuild()”?

时间:2020-06-01 07:45:54

标签: flutter dart flutter-provider

所以我有一张停泊的表,该表返回一个Future<List<..>>并包含我要制作的饼图的数据


class Stats extends StatefulWidget {

  @override
  _StatsState createState() => _StatsState();
}

class _StatsState extends State<Stats> {



  @override
  void initState() {
    super.initState();


  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        _buildTaskList(context)

      ],
    );
  }
}

FutureBuilder<List<Account>> _buildTaskList(BuildContext context) {


  Map<String, double> dataMap = Map();
  dataMap.putIfAbsent("SNACKS", () => Provider.of<Amount>(context,listen: false).snack_amount);
  dataMap.putIfAbsent("ENTERTAINMENT", () => Provider.of<Amount>(context,listen: false).entertainment_amount);
  dataMap.putIfAbsent("STATIONARY", () => Provider.of<Amount>(context,listen: false).stationary_amount);
  dataMap.putIfAbsent("OTHERS", () => Provider.of<Amount>(context,listen: false).others_amount);

  final dao = Provider.of<AccountDao>(context);
  return FutureBuilder(
    future: dao.getAllAccounts(),
    builder: (context, AsyncSnapshot<List<Account>> snapshot) {
      final accounts = snapshot.data ?? List();

      Provider.of<Amount>(context,listen: false).add(Calculate(accounts, Type.SNACKS), Calculate(accounts, Type.ENTERTAINMENT),
          Calculate(accounts, Type.STATIONARY), Calculate(accounts, Type.OTHERS));



      if (accounts == null) {
        return Text('No Accounts Yet');
      } else {
        return  PieChart(
          dataMap: dataMap,
        );
      }
    },
  );
}

double Calculate(List<Account> list, Type type){

  double sum=0;
  for(int i=0;i<list.length;i++){
    if(list[i].type==type){
      sum=sum+list[i].amount;
    }
  }

  return sum;
}

现在每次运行此命令时都会出现错误

**调度数量通知时抛出了以下断言: 在构建期间调用setState()或markNeedsBuild()。

不能将此_InheritedProviderScope小部件标记为需要构建,因为该框架已经在构建小部件。仅当其某个祖先当前正在构建窗口小部件时,才可以将其标记为需要在构建阶段中构建。允许使用此异常是因为该框架在子代之前构建父窗口小部件,这意味着将始终构建脏后代。否则,框架在此构建阶段可能不会访问此小部件。 调用setState()或markNeedsBuild()的窗口小部件为:_InheritedProviderScope 值:“金额”的实例 倾听价值 进行违规呼叫时当前正在构建的小部件为:FutureBuilder> 脏 状态:_FutureBuilderState>#37282 引发异常时,这是堆栈:

0 Element.markNeedsBuild。 (包:flutter / src / widgets / framework.dart:4167:11)

1 Element.markNeedsBuild(package:flutter / src / widgets / framework.dart:4182:6)

2 _InheritedProviderScopeElement.markNeedsNotifyDependents(软件包:provider / src / inherited_provider.dart:426:5)

3 ChangeNotifier.notifyListeners(package:flutter / src / foundation / change_notifier.dart:207:21)

4 Amount.add(package:moneymanager / main.dart:55:5)

... 金额发送通知为:“金额”实例

**

这是金额类别

class Amount extends ChangeNotifier {

  double snack_amount=0.0;
  double entertainment_amount=0.0;
  double stationary_amount=0.0;
  double  others_amount=0.0;

  void add(double snack,double entertainment,double stationary, double others){
    snack_amount=snack;
    entertainment_amount=entertainment;
    stationary_amount=stationary;
    others_amount=others;
    notifyListeners();
  }
}

获取Future<List<..>>

的函数

```Future> getAllAccounts()=> select(accounts).get();``

编辑 我按照建议编辑了答案

return FutureBuilder(
    future: dao.getAllAccounts(),
    builder: (context, AsyncSnapshot<List<Account>> snapshot) {

      if(snapshot.connectionState==ConnectionState.done){

        final accounts = snapshot.data ?? List();




        if (accounts == null) {

          return Text('No Accounts Yet');
        } else {
          Provider.of<Amount>(context,listen: false).add(Calculate(accounts, Type.SNACKS), Calculate(accounts, Type.ENTERTAINMENT),
              Calculate(accounts, Type.STATIONARY), Calculate(accounts, Type.OTHERS));

          dataMap.putIfAbsent("SNACKS", () => Provider.of<Amount>(context,listen: false).snack_amount);
          dataMap.putIfAbsent("ENTERTAINMENT", () => Provider.of<Amount>(context,listen: false).entertainment_amount);
          dataMap.putIfAbsent("STATIONARY", () => Provider.of<Amount>(context,listen: false).stationary_amount);
          dataMap.putIfAbsent("OTHERS", () => Provider.of<Amount>(context,listen: false).others_amount);


          return  PieChart(
            dataMap: dataMap,
          );
        }

      }else if(snapshot.connectionState==ConnectionState.waiting){

        return Container();
      }else{
        return Container();
      }


    },

但仍然是相同的错误

1 个答案:

答案 0 :(得分:2)

调度数量通知时抛出以下断言:在构建过程中调用setState()或markNeedsBuild()。

此错误表示您在构建阶段正在调用setState

从您记录下来,它会明确显示状态

仅当其祖先之一正在构建时,才可以将其标记为需要在构建阶段进行构建。允许使用此异常是因为该框架在子代之前构建父窗口小部件,这意味着将始终构建脏后代。否则,框架可能在此构建阶段无法访问此小部件

您可以实现ConnectionState.waiting ConnectionState.done