【问题标题】:How do I pass user input data from page to page in Flutter?如何在 Flutter 中将用户输入数据从一个页面传递到另一个页面?
【发布时间】:2025-11-29 21:25:01
【问题描述】:

我正在 Flutter 中编写一个应用程序,并尝试进行 2 页注册过程。第 1 页是他们的电子邮件、密码和重复密码,第 2 页是有关他们帐户的其他详细信息。这是个人项目的一部分。

我正在尝试将数据从第一个注册页面传递到第二个。一旦用户填写第二页并按下注册。然后整理数据并在 Authentication 和 FireStore 数据库中创建 FirebaseUser。

a) 这是正确的做法吗? AKA 将数据从一页传递到另一页。然后完成注册,但如果用户在完成第二页之前存在,那么他们还没有创建帐户。

b) 我是否应该将第二页上的信息添加到第一页上创建的帐户中?对我来说这是有道理的,但我在考虑可用性方面,没有完成完整注册过程的用户可能不希望为他们设置帐户。

我已经尝试了无数关于将数据从一个页面传递到另一个页面的教程,但是我总是遇到与无效的构造函数名称、const 错误相关的错误,或者我陷入了创建新对象和传递事物的兔子洞。

Signup.dart (第1页)

try {
          await FirebaseAuth.instance.createUserWithEmailAndPassword(email: _email, password: _password)
            .then((user) => {
              Firestore.instance.collection('users').document(user.user.uid).setData({"email": _email, "password": _password}),
            });
            Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => ExtraSignUpInfo()));

ExtraSignUpInfo.dart(第 2 页)

class ExtraSignUpInfo extends StatefulWidget {
  @override
  _ExtraSignUpInfoState createState() => _ExtraSignUpInfoState();
}

class _ExtraSignUpInfoState extends State<ExtraSignUpInfo> {
  String _name;
  String _company;
  String _jobTitle;
  String _teamName;
  String _industry;
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) {

我希望将刚刚创建的用户发送到 ExtraSignUpInfo() 页面,以便稍后在填写 ExtraSignUpInfo() 页面表单字段后创建电子邮件和密码。

【问题讨论】:

    标签: android ios firebase flutter


    【解决方案1】:

    您可以尝试使用参数传递参数并将其与命名路由调用一起发送到导航器,请参阅食谱上的此示例:

    https://flutter.dev/docs/cookbook/navigation/navigate-with-arguments

    1) 在第二个屏幕中,您必须像这样创建 ScreenArguments 类:

    class ScreenArguments {
      final String email;
      final String password;
    
      ScreenArguments(this.email, this.password);
    }
    

    2) 在第二个屏幕上启动变量:

      String email;
      String password;
    

    3) 从发送值的第一个屏幕上的按钮(例如)调用导航器:

    Navigator.pushNamed(context, "/secondScreen", arguments: email, password)
    

    *将命名路由添加到您的 main.dart 以使其正常工作。

    4) 使用从 screen1 发送到 screen2 的值。

    希望对你有帮助。

    【讨论】:

    • 啊,很好。我有类似的东西,但不是那么简单和容易。我什至没有想到pushNamed()。我创建了一个类,但总是出现某种错误。我会让你知道这是怎么回事。
    • 好的,让我知道它是否有效。这就是 Flutter 的方式,保持简单。
    【解决方案2】:

    您也可以尝试使用stepper widget,以“向导”形式在连续步骤中收集电子邮件、密码等。有很多变体(Google 'stepper widget')。

    这是一个非常基本的设置,添加一个您可以使用的TextFormField 并将验证添加到:

    import 'package:flutter/material.dart';
    
    class StepperForm extends StatefulWidget {
      static Future<void> show(BuildContext context) async {}
    
      @override
      _StepperFormState createState() => _StepperFormState();
    }
    
    class _StepperFormState extends State<StepperForm> {
      ///Stepper variables and functions
      //declare the currentStep (starting point) as an int 0
      int _currentStep = 0;
    
      //Create a list of steps. Use TextFormFields for the email/password. Add validation if needed.
      List<Step> _myStepperForm() {
        List<Step> _steps = [
          Step(
            title: Text("Enter Your Email"),
            //state: StepState.complete,
            isActive: _currentStep >= 0,
            content: TextFormField(
              decoration: InputDecoration(
                labelText: 'Email',
                suffixIcon: Icon(Icons.email),
                border: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(10),
                ),
              ),
              validator: (value) =>
              value.isNotEmpty ? null : 'email can\'t be empty',
              //Additional validation code as needed
            ),
          ),
          Step(
            title: Text("Second"),
            isActive: _currentStep >= 1,
            content: Text("My Second Example"),
          ),
          Step(
            title: Text("Third"),
            isActive: _currentStep >= 2,
            content: Text("My Third Example"),
          ),
          Step(
            title: Text("Fourth"),
            isActive: _currentStep >= 3,
            content: Text("My Fourth Example"),
          ),
        ];
        return _steps;
      }
    
      //Create function for continue button
      onStepContinue() {
        setState(() {
          if (this._currentStep < this._myStepperForm().length - 1) {
            this._currentStep = this._currentStep + 1;
          } else {
            //Completion Code
            print('The form is complete.');
          }
        });
      }
    
      //create cancel function
      onStepCancel() {
        setState(() {
          if (this._currentStep > 0) {
            this._currentStep = this._currentStep - 1;
          } else {
            this._currentStep = 0;
          }
        });
      }
    
      //Create the Stepper Widget
      Widget _stepperWidget() => Container(
            margin: EdgeInsets.only(top: 10),
            color: Colors.orangeAccent,
            child: Stepper(
              //type: StepperType.horizontal,
              currentStep: this._currentStep,
              steps: _myStepperForm(),
              onStepCancel: onStepCancel,
              onStepContinue: onStepContinue,
              onStepTapped: (step) {
                setState(() {
                  this._currentStep = step;
                });
              },
            ),
          );
    
     //Call Stepper Function in Scaffold. SingleChildScrollView helps with different screen sizes 
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('My Stepper Form'),
          ),
          body: SingleChildScrollView(
            child: Column(
              children: <Widget>[
                _stepperWidget(),
                SizedBox(height: 600)
              ],
            ),
          ),
        );
      }
    }
    
    

    【讨论】:

    • 非常感谢您!我一定会查一下,从代码中可以看出这可能正是我要找的!