我如何从Stepper TextFields中获取数据...无论字段如何,总是返回null。在这种情况下,我正在使用电子邮件进行测试。我遵循Aseem Wangoo的方法,该方法似乎在以下链接中:here。并用于我的解决方案如下:


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

class MyData {
  String _password;
  String _email;
  String _name;
  String _lastname;
}

class _SigninState extends State<Signin> {

  GlobalKey<FormState> _formKey =  GlobalKey<FormState>();
  static var _focusNode =  FocusNode();
  static MyData data = new MyData();

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

  @override
  void dispose() {
    _focusNode.dispose();
    super.dispose();
  }


  List<Step> steps = [
      Step(
        title: const Text('Crear cuenta'),
        isActive: true,
        state: StepState.indexed,
        content: Form(
          key: formKeys[0],
          child: Column(
            children: <Widget>[
              TextFormField(
                focusNode: _focusNode,
                autocorrect: false,
                onSaved: (String value) {
                  data._email = value;
                },
                maxLines: 1,
                keyboardType: TextInputType.emailAddress,
                validator: (value) {
                  if (value.isEmpty || value.length < 1) {
                    return 'Please enter name';
                  }
                },
                decoration: InputDecoration(labelText: 'Correo electrónico'),
              ),
              TextFormField(
                validator: (value) {
                if (value.isEmpty) {
                        return 'Ingrese su contraseña';
                      }
                      return null;
                },
                obscureText: true,
                autocorrect: false,
                onSaved: (String value) {
                  data._password = value;
                },
                decoration: InputDecoration(labelText: 'Contraseña'),
              ),
            ],
          ),
        )
      ),
      Step(
        isActive: true,
        state: StepState.indexed,
        title: const Text('Nombre y Apellido'),
        content: Form(
          key: formKeys[1],
          child:  Column(
            children: <Widget>[
              TextFormField(
                onSaved: (String value) {
                  data._name = value;
                },
                autocorrect: false,
                decoration: InputDecoration(labelText: 'Nombre'),
              ),
              TextFormField(
                onSaved: (String value) {
                  data._password = value;
                },
                autocorrect: false,
                decoration: InputDecoration(labelText: 'Apellido'),
              ),
            ],
          ),
        )
      ),
    ];

    int currentStep = 0;
    bool complete = false;

    next() {
      currentStep + 1 != steps.length
          ? goTo(currentStep + 1)
          : setState(() => complete = true);
    }

    cancel() {
      if (currentStep > 0) {
        goTo(currentStep - 1);
      }
    }

    goTo(int step) {
      setState(() => currentStep = step);
    }


  @override
  Widget build(BuildContext context) {
      return Scaffold(
        resizeToAvoidBottomInset: false,
        body: Stack(children: <Widget>[
          Container(
            height: double.infinity,
            width: double.infinity,
            decoration: BoxDecoration(
              gradient: LinearGradient(
                begin: Alignment.topCenter,
                end: Alignment.bottomCenter,
                colors: [
                  MustardColor,
                  FlanColor,
                  FlanLightColor
                ],
                stops: [0.1, 0.9, 1.5]
              )
            )
          ),
          Container(
            height: 180.0,
            width: 320.0,
            child: Image.asset('assets/images/crypto.png'),
            margin: const EdgeInsets.only(left: 50.0, right: 50.0, top: 20.0, bottom: 50.0),
          ),
          Center(child:
            Container(
            height: 480.0,
            width: 320.0,
            margin: const EdgeInsets.only(top: 100.0),
            decoration: BoxDecoration(
              color: FlanLightColor,
              borderRadius: BorderRadius.circular(25)
            ),
          )
          ),
          Container(
            height: 80.0,
            width: 200.0,
            child: Text('Regístrate',
              textAlign: TextAlign.center,
              style: TextStyle(
                fontFamily: 'Montserrat',
                fontSize: 30,
                fontWeight: FontWeight.w600
              ),
            ),

            margin: const EdgeInsets.only(left: 120.0, right: 120.0, top: 180.0, bottom: 100.0),
          ),
          // STEPPER

          Center(
            child: Container(
            margin: const EdgeInsets.only(top: 100),
            height: 380.0,
            width: 300.0,
            child: Form(
              key: _formKey,
              child:
                Column(
                  children: <Widget>[
                    Expanded(
                      child: Stepper(
                          steps: steps,
                          currentStep: currentStep,
                          onStepContinue: next,
                          onStepTapped: (step) => goTo(step),
                          onStepCancel: cancel,
                          controlsBuilder: (BuildContext context,
                          {VoidCallback onStepContinue, VoidCallback onStepCancel}) {
                          return Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: <Widget>[
                              SizedBox(
                                height: 80.0,
                              ),
                              FlatButton(
                                color: MustardColor,
                                onPressed: currentStep == 0 ? onStepContinue : () async {
                                  onStepContinue();
                                  // save the fields..
                                  final FormState formState = _formKey.currentState;
                                  if (!formState.validate()) {
                                    print('Please enter correct data');
                                  } else {
                                    formState.save();
                                      print("Email: ${data._email}"); // THIS RETURNS Email: Null
                                  }
                                },
                                child: currentStep == 0 ? const Text('SIGUIENTE') : const Text('FINALIZAR'),
                              ),
                              FlatButton(
                                color: GoldColor,
                                onPressed: onStepCancel,
                                child: const Text('CANCELAR'),
                              ),
                            ],
                          );
                        },
                      )
                    ),
                  ])
            )
          ))
        ],)
        );
    }
}



我的错误是什么?既不接收字段的值,也不在验证每个步骤。

最佳答案

使用TextEditingController

class _SigninState extends State<Signin> {

  GlobalKey<FormState> _formKey =  GlobalKey<FormState>();
  static var _focusNode =  FocusNode();
  static MyData data = new MyData();

 static TextEditingController _emailController = new TextEditingController();
 static TextEditingController _passwordController  = new TextEditingController();
 static TextEditingController _nameController = new TextEditingController();
 static TextEditingController _lastnameController = new TextEditingController();


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

  @override
  void dispose() {
    _focusNode.dispose();
    super.dispose();
  }


  List<Step> steps = [
    Step(
        title: const Text('Crear cuenta'),
        isActive: true,
        state: StepState.indexed,
        content: Form(
          key: formKeys[0],
          child: Column(
            children: <Widget>[
              TextFormField(
                focusNode: _focusNode,
                autocorrect: false,
                onSaved: (String value) {
                  data._email = value;
                },
                maxLines: 1,
                keyboardType: TextInputType.emailAddress,
                validator: (value) {
                  if (value.isEmpty || value.length < 1) {
                    return 'Please enter name';
                  }
                },
                controller: _emailController,
                decoration: InputDecoration(labelText: 'Correo electrónico'),
              ),
              TextFormField(
                validator: (value) {
                  if (value.isEmpty) {
                    return 'Ingrese su contraseña';
                  }
                  return null;
                },
                obscureText: true,
                autocorrect: false,
                onSaved: (String value) {
                  data._password = value;
                },
                controller: _passwordController,
                decoration: InputDecoration(labelText: 'Contraseña'),
              ),
            ],
          ),
        )
    ),
    Step(
        isActive: true,
        state: StepState.indexed,
        title: const Text('Nombre y Apellido'),
        content: Form(
          key: formKeys[1],
          child:  Column(
            children: <Widget>[
              TextFormField(
                onSaved: (String value) {
                  data._name = value;
                },
                autocorrect: false,
                controller: _nameController,
                decoration: InputDecoration(labelText: 'Nombre'),
              ),
              TextFormField(
                onSaved: (String value) {
                  data._password = value;
                },
                controller: _passwordController,
                autocorrect: false,
                decoration: InputDecoration(labelText: 'Apellido'),
              ),
            ],
          ),
        )
    ),
  ];

  int currentStep = 0;
  bool complete = false;

  next() {
    currentStep + 1 != steps.length
        ? goTo(currentStep + 1)
        : setState(() => complete = true);
  }

  cancel() {
    if (currentStep > 0) {
      goTo(currentStep - 1);
    }
  }

  goTo(int step) {
    setState(() => currentStep = step);
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
        resizeToAvoidBottomInset: false,
        body: Stack(children: <Widget>[
          Container(
              height: double.infinity,
              width: double.infinity,
              decoration: BoxDecoration(
                  gradient: LinearGradient(
                      begin: Alignment.topCenter,
                      end: Alignment.bottomCenter,
                      colors: [
                        Colors.blueAccent,
                        Colors.amber,
                        Colors.red
                      ],
                      stops: [0.1, 0.9, 1.5]
                  )
              )
          ),
          Container(
            height: 180.0,
            width: 320.0,
            child: Image.asset('assets/images/crypto.png'),
            margin: const EdgeInsets.only(left: 50.0, right: 50.0, top: 20.0, bottom: 50.0),
          ),
          Center(child:
          Container(
            height: 480.0,
            width: 320.0,
            margin: const EdgeInsets.only(top: 100.0),
            decoration: BoxDecoration(
                color: Colors.cyan,
                borderRadius: BorderRadius.circular(25)
            ),
          )
          ),
          Container(
            height: 80.0,
            width: 200.0,
            child: Text('Regístrate',
              textAlign: TextAlign.center,
              style: TextStyle(
                  fontFamily: 'Montserrat',
                  fontSize: 30,
                  fontWeight: FontWeight.w600
              ),
            ),

            margin: const EdgeInsets.only(left: 120.0, right: 120.0, top: 180.0, bottom: 100.0),
          ),
          // STEPPER

          Center(
              child: Container(
                  margin: const EdgeInsets.only(top: 100),
                  height: 380.0,
                  width: 300.0,
                  child: Form(
                      key: _formKey,
                      child:
                      Column(
                          children: <Widget>[
                            Expanded(
                                child: Stepper(
                                  steps: steps,
                                  currentStep: currentStep,
                                  onStepContinue: next,
                                  onStepTapped: (step) => goTo(step),
                                  onStepCancel: cancel,
                                  controlsBuilder: (BuildContext context,
                                      {VoidCallback onStepContinue, VoidCallback onStepCancel}) {
                                    return Row(
                                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                                      children: <Widget>[
                                        SizedBox(
                                          height: 80.0,
                                        ),
                                        FlatButton(
                                          color: Colors.green,
                                          onPressed: currentStep == 0 ? onStepContinue : () async {
                                            onStepContinue();
                                            // save the fields..
                                            final FormState formState = _formKey.currentState;
                                            if (!formState.validate()) {
                                              print('Please enter correct data');
                                            } else {
                                              formState.save();
                                              print("Email: ${_emailController.value.text}"); // THIS RETURNS Email: Null
                                            }
                                          },
                                          child: currentStep == 0 ? const Text('SIGUIENTE') : const Text('FINALIZAR'),
                                        ),
                                        FlatButton(
                                          color: Colors.amber,
                                          onPressed: onStepCancel,
                                          child: const Text('CANCELAR'),
                                        ),
                                      ],
                                    );
                                  },
                                )
                            ),
                          ])
                  )
              ))
        ],)
    );
  }
}

关于flutter - Flutter从Stepper TextFields获取数据,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/63460629/

10-11 08:55