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