提问者:小点点

Flutter get Snapshot.Data[1]在future builder中


我有以下代码

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 = 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.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]等来进行更多的查询和显示来自不同表的数据。

如有任何帮助,我们将不胜感激。


共1个答案

匿名用户

我不确定这一点,但在我的理解,一个未来建设者期望的正是一个未来。 这个未来的返回值可以通过“snapshot.data”访问。

如果您需要等待多个FutureBuilders来解决,我建议您使用多个FutureBuilders。

另一种方法是在其他地方使用future.wait()并从那里返回所有必需的数据作为一个Furure。