在构造函数中调用 SetState()

Jul*_*lia 4 checkbox setstate flutter statefulwidget

我已经建立了一个定制列表。现在我包含一个复选框,如果我选中或取消选中,则会引发以下错误:“在构造函数中调用 setState()”

\n\n
class Lists extends StatefulWidget{  \n     @override\n    _List createState() => _List();\n}\n\nclass _List extends State<Lists> {  \n  bool checkedvalue = true;\n  @override\nWidget build(BuildContext context) {\n\n return futureBuilder();\n}\n\nWidget futureBuilder(){  \n  var futureBuilder = new FutureBuilder(\n      future: rest.fetchPost(),\n      builder: (BuildContext context, AsyncSnapshot snapshot) {\n        switch (snapshot.connectionState) {\n          case ConnectionState.none:\n          case ConnectionState.waiting:\n            return new Text('loading...');\n          default:\n            if (snapshot.hasError)\n              return new Text('Error: ${snapshot.error}');\n            else                    \n                return listBuilder(context, snapshot);            \n        }\n      }\n );\n\n return new Scaffold(         \n      body: futureBuilder,\n    );\n}\n\nWidget listBuilder(BuildContext context, AsyncSnapshot snapshot) {  \n  List<rest.Status> values = snapshot.data;\n\n  if (values == null || values.length == 0){\n    return null;\n  }\n\n\n  int items = values.length;\n\n  return ListView.builder(   \n  itemCount: items,\n  itemBuilder: (BuildContext context, int index) {\n    String statusText;\n    Image image ;\n    Uint8List bytes;\n\n    if(statusList.globalStatus != null){\n      for(int i=0;i< statusList.globalStatus.length; i++){\n        if(values[index].statusID == statusList.globalStatus[i].id){\n\n            if(statusList.globalStatus[i].kurzform != null){\n              statusText = statusList.globalStatus[i].kurzform;\n            }else{\n              statusText = statusList.globalStatus[i].kurzform;\n            }\n\n            if (statusList.globalStatus[i].icon != null){\n              bytes = base64Decode(statusList.globalStatus[i].icon);\n              image = new Image.memory(bytes) ;\n            } \n        }\n\n        if(image== null || statusText == null){            \n          statusText= 'Kein Status';\n          image=  new Image.asset('assets/null.png');\n        }              \n      }\n    }   \n    return new Container( \n      decoration: new BoxDecoration(\n          border: Border(top: BorderSide(\n          color: Colors.black26,\n          width: 1\n          )\n        )\n      ), \n\n\n      child:Column(\n        children: <Widget>[\n          CustomListItemTwo( \n            statusText: statusText,                               \n            status:image,\n            materialNR: values[index].uArtText,          \n            material: values[index].untersuchungsMaterialName,\n            probenArt:  values[index].probenart,\n            eingansdatum: values[index].eingangsdatumText,\n            patient: values[index].vorname + ' ' + values[index].nachname ,\n            geburtsdatum: values[index].geburtstagText ,\n\n          ),\n          Checkbox(            \n              value: checkedvalue ,           \n              onChanged: (bool newValue) =>                \n                setState(() {\n                  checkedvalue = newValue; \n                })              \n            ),\n        ] \n      ),\n    );\n  }       \n  );\n}\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

I/flutter ( 5067): \xe2\x95\x90\xe2\x95\x90\xe2\x95\xa1 手势引发异常 \xe2\x95\x9e\xe2\x95\x90\xe2\x95\x90\xe2\ x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\ x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\ xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\ x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\ x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\ xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\ x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\ x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\nI/flutter(5067):抛出以下断言处理手势时:\nI/flutter (5067):在构造函数中调用 setState():_List#9044e(生命周期状态:已创建,无小部件,未安装)\nI/flutter (5067):当您调用 setState( 时会发生这种情况) 在尚未插入到\nI/flutter ( 5067) 的小部件的 State 对象上:尚未插入小部件树。无需在构造函数中调用 setState(),因为状态为\nI/flutter ( 5067): 在最初创建时已假定为脏状态。

\n

Leo*_*old 5

我下面的代码不是测试。

您的代码中存在一些概念错误。您应该在构建方法中获取任何内容!

如果您在构建方法中添加打印内容,例如“构建...”(正如我在下面所做的那样),您就会明白原因。构建方法的调用次数比您想象的要多。因此,您多次调用 WebService 或其他任何内容,响应就会多次出现。实际上该setState()方法将触发构建。

如果你想在一开始就拉一些东西,请使用该initState()方法。该方法将在状态创建时被调用一次。使用变量来表示调用的状态并在构建方法中对其做出反应(如前所述setState()将触发重建)。

我重构了你的代码,记住这个概念,你的开关/复选框问题可能就会消失。

另请查看如何使用 Futures https://api.flutter.dev/flutter/dart-async/Future-class.html

class Lists extends StatefulWidget {
  @override
  _List createState() => _List();
}

class _List extends State<Lists> {
  bool checkedvalue = true;
  bool loading = true;
  AsyncSnapshot asyncSnapshot = null;

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

  @override
  Widget build(BuildContext context) {
    print("building...");
    if(asyncSnapshot != null && asyncSnapshot.hasError){
      return Text("Error : ${asyncSnapshot.error}");
    }
    return (loading) ? Text("LOADING") : listBuilder(context, asyncSnapshot);
  }

  void futureBuilder() async {
    rest.fetchPost().then((snapshot) {
      switch (snapshot.connectionState) {
        case ConnectionState.none:
        case ConnectionState.waiting:
          setState(() {
            loading = true;
          });
          break;
        default:
          if (snapshot.hasError) {
            setState(() {
              loading = false;
            });
          } else {
            setState(() {
              loading = false;
              asyncSnapshot = snapshot;
            });
          }
      }
    });
  }
  .....
Run Code Online (Sandbox Code Playgroud)