Flutter 颤振中如何在页面之间传递TextEditingController的数据

Flutter 颤振中如何在页面之间传递TextEditingController的数据,flutter,Flutter,我用一页纸注册一个电话号码,然后在第二页上验证号码。现在我的问题是,我可以通过以下代码发送电话号码: await Navigator.pushNamed(context, '/otpScreen', arguments: '$_dialCode${_contactEditingController.text}'); 但我还需要从此页面发送TextEditingController(nameController)值的数据: import 'package:flutter/cupertino

我用一页纸注册一个电话号码,然后在第二页上验证号码。现在我的问题是,我可以通过以下代码发送电话号码:

 await Navigator.pushNamed(context, '/otpScreen', arguments: '$_dialCode${_contactEditingController.text}');


但我还需要从此页面发送TextEditingController(nameController)值的数据:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:onefrist/testjust/screens/login_screen/widget/country_picker.dart';
import 'package:onefrist/testjust/screens/login_screen/widget/custom_button.dart';
import 'package:onefrist/testjust/screens/otp_screen/otp_screen.dart';

import '../../../LawsOfNewUser.dart';
import '../../../loginpage.dart';


class LoginScreen extends StatefulWidget {
  @override
  _LoginScreenState createState() => _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> {
  final _contactEditingController = TextEditingController();
  final nameController = TextEditingController();
  final passwordController = TextEditingController();
  var _dialCode = '';

  //Login click with contact number validation
  Future<void> clickOnLogin(BuildContext context) async {
    if (_contactEditingController.text.isEmpty) {
      showErrorDialog(context, 'Contact number can\'t be empty.');
    } else {
      final responseMessage =
     await Navigator.pushNamed(context, '/otpScreen', arguments: '$_dialCode${_contactEditingController.text}');
      if (responseMessage != null) {
        showErrorDialog(context, responseMessage as String);

      }
    }
  }

  //callback function of country picker
  void _callBackFunction(String name, String dialCode, String flag) {
    _dialCode = dialCode;
  }

  //Alert dialogue to show error and response
  void showErrorDialog(BuildContext context, String message) {
    // set up the AlertDialog
    final CupertinoAlertDialog alert = CupertinoAlertDialog(
      title: const Text('Error'),
      content: Text('\n$message'),
      actions: <Widget>[
        CupertinoDialogAction(
          isDefaultAction: true,
          child: const Text('Yes'),
          onPressed: () {
            Navigator.of(context).pop();
          },
        )
      ],
    );
    // show the dialog
    showDialog(
      context: context,
      builder: (BuildContext context) {
        return alert;
      },
    );
  }

  //build method for UI Representation
  @override
  Widget build(BuildContext context) {
    final screenHeight = MediaQuery.of(context).size.height;
    final screenWidth = MediaQuery.of(context).size.width;
    return Scaffold(
      body: Center(
        child: SingleChildScrollView(
          child: Container(
            padding: const EdgeInsets.all(16.0),
            width: double.infinity,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.center,
              mainAxisAlignment: MainAxisAlignment.center,
              children: [

                SizedBox(
                  height: screenHeight * 0.05,
                ),
                Image.asset(
                  'assets/images/registration.png',
                  height: screenHeight * 0.3,
                  fit: BoxFit.contain,
                ),
                SizedBox(
                  height: screenHeight * 0.02,
                ),
                const Text(
                  'Login',
                  style: TextStyle(fontSize: 28, color: Colors.black),
                ),
                SizedBox(
                  height: screenHeight * 0.02,
                ),
                const Text(
                  'Enter your mobile number to receive a verification code',
                  textAlign: TextAlign.center,
                  style: TextStyle(
                    fontSize: 18,
                    color: Colors.black,
                  ),
                ),
                SizedBox(
                  height: screenHeight * 0.04,
                ),
                Container(
                  margin: EdgeInsets.symmetric(horizontal: screenWidth > 600 ? screenWidth * 0.2 : 16),
                  padding: const EdgeInsets.all(16.0),
                  decoration: BoxDecoration(
                      color: Colors.white,
                      // ignore: prefer_const_literals_to_create_immutables
                      boxShadow: [
                        const BoxShadow(
                          color: Colors.grey,
                          offset: Offset(0.0, 1.0), //(x,y)
                          blurRadius: 6.0,
                        ),
                      ],
                      borderRadius: BorderRadius.circular(16.0)),
                  child: Column(
                    children: [
                      Container(
                        margin: const EdgeInsets.all(8),
                        padding: const EdgeInsets.symmetric(horizontal: 8.0),
                        height: 45,
                        decoration: BoxDecoration(
                          border: Border.all(
                            color: const Color.fromARGB(255, 253, 188, 51),
                          ),
                          borderRadius: BorderRadius.circular(36),
                        ),
                        child: Row(
                          // ignore: prefer_const_literals_to_create_immutables
                          children: [
                            CountryPicker(
                              callBackFunction: _callBackFunction,
                              headerText: 'Select Country',
                              headerBackgroundColor: Theme.of(context).primaryColor,
                              headerTextColor: Colors.white,
                            ),
                            SizedBox(
                              width: screenWidth * 0.01,
                            ),
                            Expanded(

                              child: TextField(
                                decoration: const InputDecoration(
                                  hintText: 'Contact Number',

                                ),
                                controller: _contactEditingController,
                                keyboardType: TextInputType.number,
                                inputFormatters: [LengthLimitingTextInputFormatter(10)],
                              ),
                            ),

                          ],
                        ),
                      ),
                      const SizedBox(
                        height: 8,
                      ),

                      Container(
                        //    width: 280,
                          padding: EdgeInsets.all(5.0),
                          child: TextField(
                            maxLength: 8,
                            controller: nameController,
                            autocorrect: true,
                            decoration: InputDecoration(
                              prefixIcon:Icon(Icons.account_circle),
                              border: OutlineInputBorder(),
                              labelText: 'Enter_Your_Name_Here',
                            ),
                          )
                      ),



                      CustomButton(clickOnLogin),
                    ],
                  ),
                )
              ],
            ),
          ),
        ),
      ),
    );
  }
}


import 'dart:async';
import 'dart:convert';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

import 'package:http/http.dart' as http;

import 'package:firebase_auth/firebase_auth.dart';
import 'package:pin_entry_text_field/pin_entry_text_field.dart';

// ignore: must_be_immutable
class OtpScreen extends StatefulWidget {

  bool _isInit = true;
  var _contact = '';

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

class _OtpScreenState extends State<OtpScreen> {


  String phoneNo;
  String smsOTP;
  String verificationId;
  String errorMessage = '';
  final FirebaseAuth _auth = FirebaseAuth.instance;
  Timer _timer;

  //this is method is used to initialize data
  @override
  void didChangeDependencies() {
   // print(nameController.text);
    super.didChangeDependencies();
    // Load data only once after screen load
    if (widget._isInit) {
      widget._contact = '${ModalRoute.of(context).settings.arguments as String}';
      generateOtp(widget._contact);
      widget._isInit = false;
    }
  }

  //dispose controllers
  @override
  void dispose() {
    super.dispose();
  }




  //build method for UI
  @override
  Widget build(BuildContext context) {

    final screenHeight = MediaQuery.of(context).size.height;
    final screenWidth = MediaQuery.of(context).size.width;
    return Scaffold(
      body: Center(
        child: SingleChildScrollView(
          child: Container(
            padding: const EdgeInsets.all(16.0),
            width: double.infinity,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.center,
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                SizedBox(
                  height: screenHeight * 0.05,
                ),
                Image.asset(
                  'assets/images/logo.png',
                  width: screenWidth * 0.7,
                  fit: BoxFit.contain,
                ),
                SizedBox(
                  height: screenHeight * 0.05,
                ),

                SizedBox(
                  height: screenHeight * 0.02,
                ),
                const Text(
                  'Verification',
                  style: TextStyle(fontSize: 28, color: Colors.black),
                ),
                SizedBox(
                  height: screenHeight * 0.02,
                ),

                Text(
                  'Enter A 6 digit number that was sent to ${widget._contact}',
                  textAlign: TextAlign.center,
                  style: const TextStyle(
                    fontSize: 18,
                    color: Colors.black,
                  ),
                ),






                SizedBox(
                  height: screenHeight * 0.04,
                ),
                Container(
                  margin: EdgeInsets.symmetric(horizontal: screenWidth > 600 ? screenWidth * 0.2 : 16),
                  padding: const EdgeInsets.all(16.0),
                  decoration: BoxDecoration(
                      color: Colors.white,
                      // ignore: prefer_const_literals_to_create_immutables
                      boxShadow: [
                        const BoxShadow(
                          color: Colors.grey,
                          offset: Offset(0.0, 1.0), //(x,y)
                          blurRadius: 6.0,
                        ),
                      ],
                      borderRadius: BorderRadius.circular(16.0)),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.center,
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Container(
                        margin: EdgeInsets.only(left: screenWidth * 0.025),
                        child: PinEntryTextField(
                          fields: 6,
                          onSubmit: (text) {
                            smsOTP = text as String;
                          },
                        ),
                      ),


                      SizedBox(
                        height: screenHeight * 0.04,
                      ),
                      GestureDetector(
                        onTap: () {
                          verifyOtp();
                        },
                        child: Container(
                          margin: const EdgeInsets.all(8),
                          height: 45,
                          width: double.infinity,
                          decoration: BoxDecoration(
                            color: const Color.fromARGB(255, 253, 188, 51),
                            borderRadius: BorderRadius.circular(36),
                          ),
                          alignment: Alignment.center,
                          child: const Text(
                            'Verify',
                            style: TextStyle(color: Colors.black, fontSize: 16.0),
                          ),
                        ),
                      ),
                    ],
                  ),
                )
              ],
            ),
          ),
        ),
      ),
    );
  }

  //Method for generate otp from firebase
  Future<void> generateOtp(String contact) async {
    final PhoneCodeSent smsOTPSent = (String verId, [int forceCodeResend]) {
      verificationId = verId;
    };
    try {
      await _auth.verifyPhoneNumber(
          phoneNumber: contact,
          codeAutoRetrievalTimeout: (String verId) {
            verificationId = verId;
          },
          codeSent: smsOTPSent,
          timeout: const Duration(seconds: 60),
          verificationCompleted: (AuthCredential phoneAuthCredential) {},
          verificationFailed: (AuthException exception) {
           // Navigator.pop(context, exception.message);
          });
    } catch (e) {
      handleError(e as PlatformException);
     // Navigator.pop(context, (e as PlatformException).message);
    }
  }

  //Method for verify otp entered by user
  Future<void> verifyOtp() async {
    if (smsOTP == null || smsOTP == '') {
      showAlertDialog(context, 'please enter 6 digit otp');
      return;
    }
    try {
      final AuthCredential credential = PhoneAuthProvider.getCredential(
        verificationId: verificationId,
        smsCode: smsOTP,
      );
      final AuthResult user = await _auth.signInWithCredential(credential);
      final FirebaseUser currentUser = await _auth.currentUser();
      assert(user.user.uid == currentUser.uid);

      Navigator.pushReplacementNamed(context, '/homeScreen');
    } catch (e) {
      handleError(e as PlatformException);
    }
  }

  //Method for handle the errors
  void handleError(PlatformException error) {
    switch (error.code) {
      case 'ERROR_INVALID_VERIFICATION_CODE':
        FocusScope.of(context).requestFocus(FocusNode());
        setState(() {
          errorMessage = 'Invalid Code';
        });
        showAlertDialog(context, 'Invalid Code');
        break;
      default:
        showAlertDialog(context, error.message);
        break;
    }
  }

  //Basic alert dialogue for alert errors and confirmations
  void showAlertDialog(BuildContext context, String message) {
    // set up the AlertDialog
    final CupertinoAlertDialog alert = CupertinoAlertDialog(
      title: const Text('Error'),
      content: Text('\n$message'),
      actions: <Widget>[
        CupertinoDialogAction(
          isDefaultAction: true,
          child: const Text('Ok'),
          onPressed: () {
            Navigator.of(context).pop();
          },
        )
      ],
    );
    // show the dialog
    showDialog(
      context: context,
      builder: (BuildContext context) {
        return alert;
      },
    );
  }

}

import'包装:flift/cupertino.dart';
进口“包装:颤振/材料.省道”;
导入“包:flifter/services.dart”;
导入“包:onefrist/testjust/screens/login\u screen/widget/country\u picker.dart”;
导入“包:onefrist/testjust/screens/login_screen/widget/custom_button.dart”;
导入“包:onefirst/testjust/screens/otp_screen/otp_screen.dart”;
导入“../../LawsOfNewUser.dart”;
导入“../../loginpage.dart”;
类LoginScreen扩展StatefulWidget{
@凌驾
_LoginsScreenState createState()=>\u LoginsScreenState();
}
类_LoginScreenState扩展状态{
最终_contactEditingController=TextEditingController();
最终名称控制器=TextEditingController();
最终密码控制器=TextEditingController();
变量_dialCode='';
//使用联系人号码验证登录
将来的clickOnLogin(构建上下文上下文)异步{
if(_contactEditingController.text.isEmpty){
对话(上下文“联系人号码不能为空”);
}否则{
最终响应消息=
wait Navigator.pushNamed(上下文“/otpScreen”,参数:“$\u dialCode${\u contactEditingController.text}”);
if(responseMessage!=null){
对话框(上下文、响应消息作为字符串);
}
}
}
//国家选择器的回调函数
void\u callBackFunction(字符串名称、字符串拨号代码、字符串标志){
_拨号代码=拨号代码;
}
//警报对话框显示错误和响应
无效对话框(BuildContext上下文,字符串消息){
//设置警报对话框
最终CupertinoAlertDialog警报=CupertinoAlertDialog(
标题:常量文本(“错误”),
内容:文本(“\n$message”),
行动:[
铜中毒(
isDefaultAction:对,
子项:常量文本(“是”),
已按下:(){
Navigator.of(context.pop();
},
)
],
);
//显示对话框
显示对话框(
上下文:上下文,
生成器:(BuildContext上下文){
返回警报;
},
);
}
//UI表示的构建方法
@凌驾
小部件构建(构建上下文){
最终屏幕高度=MediaQuery.of(context).size.height;
最终屏幕宽度=MediaQuery.of(context).size.width;
返回脚手架(
正文:中(
子:SingleChildScrollView(
子:容器(
填充:常数边集全部(16.0),
宽度:double.infinity,
子:列(
crossAxisAlignment:crossAxisAlignment.center,
mainAxisAlignment:mainAxisAlignment.center,
儿童:[
大小盒子(
高度:屏幕高度*0.05,
),
影像资产(
“assets/images/registration.png”,
高度:屏幕高度*0.3,
适合:BoxFit.contain,
),
大小盒子(
高度:屏幕高度*0.02,
),
常量文本(
“登录”,
样式:TextStyle(字体大小:28,颜色:Colors.black),
),
大小盒子(
高度:屏幕高度*0.02,
),
常量文本(
'输入您的手机号码以接收验证码',
textAlign:textAlign.center,
样式:TextStyle(
尺码:18,
颜色:颜色,黑色,
),
),
大小盒子(
高度:屏幕高度*0.04,
),
容器(
边距:边缘集。对称(水平:屏幕宽度>600?屏幕宽度*0.2:16),
填充:常数边集全部(16.0),
装饰:盒子装饰(
颜色:颜色,白色,
//忽略:宁愿使用常量文本也不创建不可变
boxShadow:[
常数盒影(
颜色:颜色。灰色,
偏移量:偏移量(0.0,1.0),/(x,y)
半径:6.0,
),
],
边界半径:边界半径。圆形(16.0)),
子:列(
儿童:[
容器(
边距:常数边集全部(8),
填充:常量边集。对称(水平:8.0),
身高:45,
装饰:盒子装饰(
边界:边界(
颜色:常量颜色。来自argb(255、253、188、51),
),
边界半径:边界半径。圆形(36),
),
孩子:排(
//忽略:宁愿使用常量文本也不创建不可变
儿童:[
乡村采摘者(
callBackFunction:_callBackFunction,
标题文字:“选择国家”,
headerBackgroundColor:Theme.of(context).primaryColor,
headerTextColor:Colors.white,
),
大小盒子(
宽度:屏幕宽度*0.01,
),
扩大(
孩子:TextField(
装饰:常量输入装饰
arguments: ScreenArguments(
                contact: _contactEditingController.text,
                name: nameController.text,
              ),
args = ModalRoute.of(context).settings.arguments;
widget._contact = args.contact;
name = args.name;
class ScreenArguments {
  final String contact;
  final String name;

  ScreenArguments({this.contact, this.name});
}
...
Navigator.pushNamed(
                  context,
                  "/otpScreen",
                  arguments: ScreenArguments(
                    contact: _contactEditingController.text,
                    name: nameController.text,
                  ),
                );
...             
class _OtpScreenState extends State<OtpScreen> {
  ScreenArguments args;
  String name = "";

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    // Load data only once after screen load
    if (widget._isInit) {
      args = ModalRoute.of(context).settings.arguments;
      widget._contact = args.contact;
      name = args.name;
      //generateOtp(widget._contact);
      widget._isInit = false;
    }               
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Navigation with Arguments',
        home: LoginScreen(),
        routes: {
          "/otpScreen": (context) => OtpScreen(),
        });
  }
}

class LoginScreen extends StatefulWidget {
  @override
  _LoginScreenState createState() => _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> {
  final _contactEditingController = TextEditingController();
  final nameController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home Screen'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            TextField(
              decoration: const InputDecoration(
                hintText: 'Contact Number',
              ),
              controller: _contactEditingController,
              keyboardType: TextInputType.number,
              inputFormatters: [LengthLimitingTextInputFormatter(10)],
            ),
            TextField(
              maxLength: 8,
              controller: nameController,
              autocorrect: true,
              decoration: InputDecoration(
                prefixIcon: Icon(Icons.account_circle),
                border: OutlineInputBorder(),
                labelText: 'Enter_Your_Name_Here',
              ),
            ),
            ElevatedButton(
              child: Text("Navigate to a named that accepts arguments"),
              onPressed: () {
                Navigator.pushNamed(
                  context,
                  "/otpScreen",
                  arguments: ScreenArguments(
                    contact: _contactEditingController.text,
                    name: nameController.text,
                  ),
                );
              },
            ),
          ],
        ),
      ),
    );
  }
}

// ignore: must_be_immutable
class OtpScreen extends StatefulWidget {
  bool _isInit = true;
  var _contact = '';

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

class _OtpScreenState extends State<OtpScreen> {
  ScreenArguments args;
  String name = "";

  @override
  void didChangeDependencies() {   
    super.didChangeDependencies();
    // Load data only once after screen load
    if (widget._isInit) {
      args = ModalRoute.of(context).settings.arguments;
      widget._contact = args.contact;
      name = args.name;
      //generateOtp(widget._contact);
      widget._isInit = false;
    }
  }

  @override
  Widget build(BuildContext context) {   
    return Scaffold(
      appBar: AppBar(
        title: Text(args.contact),
      ),
      body: Center(
        child: Text(args.name),
      ),
    );
  }
}

class ScreenArguments {
  final String contact;
  final String name;

  ScreenArguments({this.contact, this.name});
}