首页 > 解决方案 > Flutter 在未来的 builder 中获取 snapshot.data[1]

问题描述

我有以下代码

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;
  Future<List<String>> _car;

  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();
  }

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

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

    _future = getData();
    _car = getCar();

    _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.wait([_future, _car]),
        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[0]
                              .map((languages) => FormBuilderFieldOption(
                              value: languages, child: Text("$languages")))
                              .toList(),
                        ),
                      ),
                    ],
                  ),
                ),
              ),
              Step(
                title: const Text('Users'),
                //subtitle: const Text('Subtitle'),
                isActive: true,
                //state: StepState.editing,
                state: StepState.indexed,
                content: Form(
                  key: formKeys[1],
                  child: Column(
                    children: <Widget>[
                      FormBuilder(
                        key: _fbKey,
                        autovalidate: true,
                        child: FormBuilderCheckboxList(
                          decoration:
                          InputDecoration(labelText: "Cars"),
                          attribute: "cars",
                          initialValue: ["BM-WD01"],
                          options: snapshot.data[1]
                              .map((car) => FormBuilderFieldOption(
                              value: car, child: Text("$car")))
                              .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(),

        ));
  }
}

我想显示来自 mySQL 的多个列表,第一个函数 _future 工作正常,但是当我替换future: _future

future: Future.wait([_future, _car]),

我得到一个

元素类型“Future<List>”不能分配给列表类型“Future”

我尝试了许多其他解决方案,但它们都不能使用 snapshot.data[0]、snapshot.data 1等等来显示来自不同表的更多查询和数据。

无法与更多的未来建设者合作,这对于自己的每一步来说都会更容易,但后来我明白了 在此处输入图像描述

      Step(
        title: const Text('Users'),
        //subtitle: const Text('Subtitle'),
        isActive: true,
        //state: StepState.editing,
        state: StepState.indexed,
        content: Form(
          key: formKeys[0],
          child:  FutureBuilder<List>(
            future: _future,
              // ignore: missing_return
            builder: (BuildContext context, snapshot) {
              if (snapshot.connectionState == ConnectionState.done) {
                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(),


                      ),
                    ),
                  ],
                );
              }
            }
        ),
        ),
      ),
    ];

任何帮助,将不胜感激。

标签: mysqldart

解决方案


该问题的工作解决方案。如果有更好的方法欢迎留言:)

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;
  Future<List<String>> _getcar;

  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() async {
    final response = await http.post(
        _api + "insert_data.php?key=" + _key, body: {
    });
    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();
  }

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


  Widget getdis2(BuildContext context) {
    return FutureBuilder<List<String>>(
      future: _getcar, // a previously-obtained Future<String> or null
      builder: (BuildContext context, AsyncSnapshot<List<String>> snapshot) {
        List<Widget> children;
        if (snapshot.hasData) {
          children = <Widget>[
            FormBuilderCheckboxList(
              decoration:
              InputDecoration(
                  labelText: "Languages you know"),
              attribute: "languages",
              initialValue: ["English"],
              options: snapshot.data
                  .map((gender) =>
                  FormBuilderFieldOption(
                      value: gender, child: Text("$gender")))
                  .toList(),
            ),
          ];
        } else if (snapshot.hasError) {
          children = <Widget>[
            Icon(
              Icons.error_outline,
              color: Colors.red,
              size: 60,
            ),
            Padding(
              padding: const EdgeInsets.only(top: 16),
              child: Text('Error: ${snapshot.error}'),
            )
          ];
        } else {
          children = <Widget>[
            SizedBox(
              child: CircularProgressIndicator(),
              width: 60,
              height: 60,
            ),
            const Padding(
              padding: EdgeInsets.only(top: 16),
              child: Text('Awaiting result...'),
            )
          ];
        }
        return Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: children,
          ),
        );
      },
    );

  }

  Widget getdis(BuildContext context) {
    return FutureBuilder<List<String>>(
        future: _future, // a previously-obtained Future<String> or null
        builder: (BuildContext context, AsyncSnapshot<List<String>> snapshot) {
          List<Widget> children;
          if (snapshot.hasData) {
            children = <Widget>[
              FormBuilderCheckboxList(
                decoration:
                InputDecoration(
                    labelText: "Languages you know"),
                attribute: "languages",
                initialValue: ["English"],
                options: snapshot.data
                    .map((gender) =>
                    FormBuilderFieldOption(
                        value: gender, child: Text("$gender")))
                    .toList(),
              ),
            ];
          } else if (snapshot.hasError) {
            children = <Widget>[
              Icon(
                Icons.error_outline,
                color: Colors.red,
                size: 60,
              ),
              Padding(
                padding: const EdgeInsets.only(top: 16),
                child: Text('Error: ${snapshot.error}'),
              )
            ];
          } else {
            children = <Widget>[
              SizedBox(
                child: CircularProgressIndicator(),
                width: 60,
                height: 60,
              ),
              const Padding(
                padding: EdgeInsets.only(top: 16),
                child: Text('Awaiting result...'),
              )
            ];
          }
          return Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: children,
            ),
          );
        },
      );

  }

  @override
  void initState() {
    super.initState();
    _future = getData();
    _getcar = getCar();

    _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() {
      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: ");


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


    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: getdis(context),
        ),
      ),
      Step(
        title: const Text('Cars'),
        //subtitle: const Text('Subtitle'),
        isActive: true,
        //state: StepState.editing,
        state: StepState.indexed,
        content: Form(
          key: formKeys[1],
          child: getdis2(context),
        ),
      ),
    ];

    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(),

        ));
  }
}

推荐阅读