【问题标题】:Flutter insert list from mySQL to options in FormBuilderCheckboxListFlutter 将 mySQL 中的列表插入到 FormBuilderCheckboxList 中的选项中
【发布时间】:2020-10-22 00:46:23
【问题描述】:

我正在从 mySQL 获取数据作为用户列表。

在formbuilder中有一个列表作为例子:

['English', 'German', 'French']

我已将其更改为 options: item,它曾经工作过,但现在出现错误

在构建 StepperBody(dirty, state: _StepperBodyState#98968) 时引发了以下 NoSuchMethodError: 在 null 上调用了方法“map”。 接收方:空 尝试调用:map(Closure: (dynamic) => FormBuilderFieldOption)

它已经工作了几次,应用程序重新启动后它停止工作,所以我将其更改回当前列表。

如何将异步列表分配给表单生成器?

代码:

import 'dart:math';
import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
//import 'package:validate/validate.dart';  //for validation
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:intl/intl.dart';
import 'main_.dart';

class MyData {
  String title;
  String days;
  String words;
  String rep;
  String gender;
  var username;

  MyData({this.gender, this.title, this.days, this.words, this.rep, this.username,
  });

}

class StepperBody extends StatefulWidget {
  @override
  _StepperBodyState createState() => _StepperBodyState();
}

class _StepperBodyState extends State<StepperBody> {
  int currStep = 0;
  static var _focusNode = FocusNode();
  GlobalKey<FormState> _formKey = GlobalKey<FormState>();
  final GlobalKey<FormBuilderState> _fbKey = GlobalKey<FormBuilderState>();

  static MyData data = MyData();


  List<GlobalKey<FormState>> formKeys = [
    GlobalKey<FormState>(),
    GlobalKey<FormState>(),
    GlobalKey<FormState>(),
    GlobalKey<FormState>()
  ];

  String _key = "786465659081B207EB5BF1EF9AF7552A6";
  String _api = "https://10.0.2.2/api/";

  Future<List> senddata() async {
    final response = await http.post(
        _api + "insert_data.php?key=" + _key, body: {
      "username": data.username,
    });
    var resp = jsonDecode(response.body);
    print(resp.toString());
  }

  Future<List> getData() async{
    var url = _api + "get_data.php?key=" + _key;
    http.Response response = await http.get(url);
    var resp = jsonDecode(response.body);
    print(resp.toString());
    data.username = resp.map<String>((m) => m['username'] as String).toList();
    print(data.username);
  }
  List item = data.username as List;


  List<Step> steps = [];


  @override
  void initState() {
    super.initState();
    getData();
    _focusNode.addListener(() {
      setState(() {});
      print('Has focus: $_focusNode.hasFocus');
    });
  }


  @override
  Widget build(BuildContext context) {
    steps = [
      Step(
          title: const Text('Users'),
          //subtitle: const Text('Subtitle'),
          isActive: true,
          //state: StepState.editing,
          state: StepState.indexed,
          content: Form(
            key: formKeys[0],
            child: Column(
              children: <Widget>[
              FormBuilder(
              key: _fbKey,
              autovalidate: true,
               child: FormBuilderCheckboxList(
                  decoration:
                  InputDecoration(labelText: "Languages you know"),
                  attribute: "languages",
                  initialValue: ["English"],
                  options: ['English', 'German', 'French']
                  .map((gender) => FormBuilderFieldOption(
                   value: gender, child: Text("$gender")))
                  .toList(),
                  ),
                ),
              ],
            ),
          ),
      ),
    ];

    void showSnackBarMessage(String message,
        [MaterialColor color = Colors.red]) {
      Scaffold.of(context).showSnackBar(SnackBar(content: Text(message)));
    }

    void _submitDetails() {
      final FormState formState = _formKey.currentState;
      final FormBuilderState fbKeyState = _fbKey.currentState;
/*
      _fbKey.currentState.save();
      if (_fbKey.currentState.validate()) {
        print(_fbKey.currentState.value);
      }

 */
      if (!fbKeyState.validate()) {
        showSnackBarMessage('Please enter correct data');
        senddata();

      } else {
        showSnackBarMessage('Saved');
        formState.save();
        senddata();
          print("Name: ${data.username}");



        _fbKey.currentState.save();
        if (_fbKey.currentState.validate()) {
          print(_fbKey.currentState.value);
        }
      }
    }

    return Container(
        child: Form(
          key: _formKey,
          child: ListView(children: <Widget>[
            Stepper(
              steps: steps,
              physics: ClampingScrollPhysics(),
              type: StepperType.vertical,
              currentStep: this.currStep,
              onStepContinue: () {
                setState(() {
                  if (formKeys[currStep].currentState.validate()) {
                    if (currStep < steps.length - 1) {
                      currStep = currStep + 1;
                    } else {
                      currStep = 0;
                    }
                  }
                  // else {
                  // Scaffold
                  //     .of(context)
                  //     .showSnackBar( SnackBar(content:  Text('$currStep')));

                  // if (currStep == 1) {
                  //   print('First Step');
                  //   print('object' + FocusScope.of(context).toStringDeep());
                  // }

                  // }
                });
              },
              controlsBuilder: (BuildContext context,
                  {VoidCallback onStepContinue, VoidCallback onStepCancel}) {
                return Row(
                  //   mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: <Widget>[
                    //
                    RaisedButton(
                      color: Colors.red,
                      child: Text("Forward", style: TextStyle(color:Colors.white)),
                      onPressed: onStepContinue,
                    ),

                    SizedBox(width: 15,),
                    RaisedButton(
                      color: Colors.red,
                      child: Text("Back", style: TextStyle(color:Colors.white)),
                      onPressed: onStepCancel,
                    ),
                  ],
                );
              },
              onStepCancel: () {
                setState(() {
                  if (currStep > 0) {
                    currStep = currStep - 1;
                  } else {
                    currStep = 0;
                  }
                });
              },
              onStepTapped: (step) {
                setState(() {
                  currStep = step;
                });
              },
            ),

            RaisedButton(
              child: Text(
                'Save',
                style: TextStyle(color: Colors.white),
              ),
              onPressed: () {
                var submitDetails = _submitDetails;
                submitDetails();
              },
              color: Colors.lightGreen,
            ),
          ]),
        ));
  }
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: "test",),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class MyAppScreenMode extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {

    return new MaterialApp(
        theme: new ThemeData(
          primarySwatch: Colors.red,
        ),
        home: new Scaffold(

          appBar: new AppBar(
            title: new Text('Test stepper'),
          ),
          body: new StepperBody(),

        ));
  }
}

感谢您的帮助!

【问题讨论】:

    标签: mysql flutter dart


    【解决方案1】:

    您收到此错误的原因是在执行build 方法时data.username 的值为空。这是因为 username 属性的值仅在从数据库异步获取后才设置,此时 build 方法可能已经执行,也可能尚未执行。我已更新您的代码示例,以展示如何使用 FutureBuilder 小部件等待从数据库异步获取数据,然后再将其显示在 FormBuilderCheckboxList 小部件中。我建议您查看文档 here 以获取有关 FutureBuilder 小部件的更多信息。

    import 'package:flutter/material.dart';
    import 'package:flutter/rendering.dart';
    import 'dart:async';
    import 'dart:convert';
    import 'package:http/http.dart' as http;
    import 'package:flutter_form_builder/flutter_form_builder.dart';
    
    class MyData {
      String title;
      String days;
      String words;
      String rep;
      String gender;
      var username;
    
      MyData({this.gender, this.title, this.days, this.words, this.rep, this.username,
      });
    
    }
    
    class StepperBody extends StatefulWidget {
      @override
      _StepperBodyState createState() => _StepperBodyState();
    }
    
    class _StepperBodyState extends State<StepperBody> {
      int currStep = 0;
      static var _focusNode = FocusNode();
      GlobalKey<FormState> _formKey = GlobalKey<FormState>();
      final GlobalKey<FormBuilderState> _fbKey = GlobalKey<FormBuilderState>();
      Future<List<String>> _future;
    
      List<GlobalKey<FormState>> formKeys = [
        GlobalKey<FormState>(),
        GlobalKey<FormState>(),
        GlobalKey<FormState>(),
        GlobalKey<FormState>()
      ];
    
      String _key = "786465659081B207EB5BF1EF9AF7552A6";
      String _api = "https://10.0.2.2/api/";
    
      Future<void> senddata(List<String> username) async {
        final response = await http.post(
            _api + "insert_data.php?key=" + _key, body: {
          "username": username,
        });
        var resp = jsonDecode(response.body);
        print(resp.toString());
      }
    
      Future<List<String>> getData() async {
        var url = _api + "get_data.php?key=" + _key;
        http.Response response = await http.get(url);
        var resp = jsonDecode(response.body);
        print(resp.toString());
        return resp.map<String>((m) => m['username'] as String).toList();
      }
    
      @override
      void initState() {
        super.initState();
    
        _future = getData();
    
        _focusNode.addListener(() {
          setState(() {});
          print('Has focus: $_focusNode.hasFocus');
        });
      }
    
    
      @override
      Widget build(BuildContext context) {
        void showSnackBarMessage(String message,
            [MaterialColor color = Colors.red]) {
          Scaffold.of(context).showSnackBar(SnackBar(content: Text(message)));
        }
    
        void _submitDetails(List<String> username) {
          final FormState formState = _formKey.currentState;
          final FormBuilderState fbKeyState = _fbKey.currentState;
    /*
          _fbKey.currentState.save();
          if (_fbKey.currentState.validate()) {
            print(_fbKey.currentState.value);
          }
    
     */
          if (!fbKeyState.validate()) {
            showSnackBarMessage('Please enter correct data');
            senddata(username);
    
          } else {
            showSnackBarMessage('Saved');
            formState.save();
            senddata(username);
            print("Name: $username");
    
    
    
            _fbKey.currentState.save();
            if (_fbKey.currentState.validate()) {
              print(_fbKey.currentState.value);
            }
          }
        }
    
        return FutureBuilder<List<String>>(
          future: _future,
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.done) {
              final steps = [
                Step(
                  title: const Text('Users'),
                  //subtitle: const Text('Subtitle'),
                  isActive: true,
                  //state: StepState.editing,
                  state: StepState.indexed,
                  content: Form(
                    key: formKeys[0],
                    child: Column(
                      children: <Widget>[
                        FormBuilder(
                          key: _fbKey,
                          autovalidate: true,
                          child: FormBuilderCheckboxList(
                            decoration:
                            InputDecoration(labelText: "Languages you know"),
                            attribute: "languages",
                            initialValue: ["English"],
                            options: snapshot.data
                                .map((gender) => FormBuilderFieldOption(
                                value: gender, child: Text("$gender")))
                                .toList(),
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
              ];
    
              return Container(
                  child: Form(
                    key: _formKey,
                    child: ListView(children: <Widget>[
                      Stepper(
                        steps: steps,
                        physics: ClampingScrollPhysics(),
                        type: StepperType.vertical,
                        currentStep: this.currStep,
                        onStepContinue: () {
                          setState(() {
                            if (formKeys[currStep].currentState.validate()) {
                              if (currStep < steps.length - 1) {
                                currStep = currStep + 1;
                              } else {
                                currStep = 0;
                              }
                            }
                            // else {
                            // Scaffold
                            //     .of(context)
                            //     .showSnackBar( SnackBar(content:  Text('$currStep')));
    
                            // if (currStep == 1) {
                            //   print('First Step');
                            //   print('object' + FocusScope.of(context).toStringDeep());
                            // }
    
                            // }
                          });
                        },
                        controlsBuilder: (BuildContext context,
                            {VoidCallback onStepContinue, VoidCallback onStepCancel}) {
                          return Row(
                            //   mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: <Widget>[
                              //
                              RaisedButton(
                                color: Colors.red,
                                child: Text("Forward",
                                    style: TextStyle(color: Colors.white)),
                                onPressed: onStepContinue,
                              ),
    
                              SizedBox(width: 15,),
                              RaisedButton(
                                color: Colors.red,
                                child: Text(
                                    "Back", style: TextStyle(color: Colors.white)),
                                onPressed: onStepCancel,
                              ),
                            ],
                          );
                        },
                        onStepCancel: () {
                          setState(() {
                            if (currStep > 0) {
                              currStep = currStep - 1;
                            } else {
                              currStep = 0;
                            }
                          });
                        },
                        onStepTapped: (step) {
                          setState(() {
                            currStep = step;
                          });
                        },
                      ),
    
                      RaisedButton(
                        child: Text(
                          'Save',
                          style: TextStyle(color: Colors.white),
                        ),
                        onPressed: () {
                          var submitDetails = _submitDetails;
                          submitDetails(snapshot.data);
                        },
                        color: Colors.lightGreen,
                      ),
                    ]),
                  ));
            } else {
              return CircularProgressIndicator();
            }
          }
        );
      }
    }
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(title: "test",),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      MyAppScreenMode createState() => MyAppScreenMode();
    }
    
    class MyAppScreenMode extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
    
        return new MaterialApp(
            theme: new ThemeData(
              primarySwatch: Colors.red,
            ),
            home: new Scaffold(
    
              appBar: new AppBar(
                title: new Text('Test stepper'),
              ),
              body: new StepperBody(),
    
            ));
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-19
      • 1970-01-01
      • 1970-01-01
      • 2018-06-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多