Flutter跳转界面
跳转界面是通过进栈和出栈的方式进行的
最简单的跳转方式如下
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const ResetPasswordSubmitStateless()),
);
出栈方式
Navigator.pop(context);
如果你想出两个栈就如下
Navigator.pop(context);
Navigator.pop(context);
如果你想带参数跳转
Navigator.push(context,
MaterialPageRoute(builder: (BuildContext context) {
return ResetPasswordSubmit(//这个是要跳转的界面
userPhone: _userPhoneController.text,//参数一
userCode: _AuthCodeController.text,//参数二
);
}));
接收的地方
class ResetPasswordSubmit extends StatefulWidget {
String userPhone;//全局
String userCode;
ResetPasswordSubmit({key, this.userPhone, this.userCode}) : super(key: key);//这里接收
@override
ResetPasswordSubmitState createState() => ResetPasswordSubmitState();
}
使用如下
print("${widget.userPhone}");
print("${widget.userCode}");
第一个界面如下
import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'DialogRouter.dart';
import 'LoadingDialog.dart';
import 'ResetPasswordSubmit.dart';
import 'data/AuthCode.dart';
//重置密码界面
//无状态组件用于跳转界面
class ResetPasswordStateless extends StatelessWidget {
const ResetPasswordStateless({key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(home: ResetPassword());
}
}
//有状态组件用来布置控件
class ResetPassword extends StatefulWidget {
const ResetPassword({key}) : super(key: key);
@override
ResetPasswordState createState() => ResetPasswordState();
}
class ResetPasswordState extends State<ResetPassword> {
//焦点
final FocusNode _focusNodePhone = FocusNode();
final FocusNode _focusNodePassWord = FocusNode();
//输入框控制器
final TextEditingController _userPhoneController = TextEditingController();
final TextEditingController _AuthCodeController = TextEditingController();
@override
void initState() {
// TODO: implement initState
//设置焦点监听
_focusNodePhone.addListener(_focusNodeListener);
_focusNodePassWord.addListener(_focusNodeListener);
super.initState();
}
@override
void dispose() {
// TODO: implement dispose
// 移除焦点监听
_focusNodePhone.removeListener(_focusNodeListener);
_focusNodePassWord.removeListener(_focusNodeListener);
super.dispose();
}
// 监听焦点
Future<Null> _focusNodeListener() async {
if (_focusNodePhone.hasFocus) {
// 取消验证码的焦点状态
_focusNodePassWord.unfocus();
}
if (_focusNodePassWord.hasFocus) {
// 取消手机号焦点状态
_focusNodePhone.unfocus();
}
}
//发送验证码接口
sendAuthCode() async {
var apiUrl = "http://47.242.63.216:9527/v1/user/sendAuthCode";
//参数
Map map = {};
//ID写死
map["app_id"] = "10001";
//手机区号(可不填,不填代表已有账号)
map["country_code"] = "zh_tw";
//手机号
map["phone"] = _userPhoneController.text;
//短信类型 不填或0为注册验证码 1为重置密码验证码
map["sms_type"] = 1;
Response result = await Dio().post(apiUrl, data: map);
debugPrint("发送验证码接口返回${result}");
//json解析
Map<String, dynamic> authCode = json.decode(result.toString());
var mes = AuthCode.fromJson(authCode);
if (mes.code == 200) {
Fluttertoast.showToast(
msg: "验证码:${mes.data.authCode}",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 10,
backgroundColor: Colors.white,
textColor: Colors.black,
fontSize: 16.0);
//请求成功后一个组件出栈,就是去掉弹窗
Navigator.pop(context);
}
}
@override
Widget build(BuildContext context) {
//输入文本框区域
Widget inputTextArea = Container(
margin: const EdgeInsets.only(left: 60, right: 60, top: 70),
child: Form(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Row(
children: [
Container(
margin: const EdgeInsets.only(right: 10),
child: const Text(
"手機號",
style: TextStyle(color: Color(0xFFA8A8A8), fontSize: 14),
),
),
Container(
height: 50,
width: 200,
child: TextFormField(
controller: _userPhoneController,
focusNode: _focusNodePhone,
style: const TextStyle(color: Colors.white),
//设置键盘类型
keyboardType: TextInputType.number,
decoration: const InputDecoration(
//取消编辑框的下边框
border: OutlineInputBorder(borderSide: BorderSide.none),
hintText: "請鍵入你的手機號碼",
hintStyle:
TextStyle(color: Color(0xFF54514C), fontSize: 14),
),
),
),
],
),
//分割线
Container(
margin: const EdgeInsets.only(bottom: 26),
height: 1,
decoration: const BoxDecoration(color: Color(0xFF3B3631)),
),
//验证码那一行
Row(
children: [
Container(
margin: const EdgeInsets.only(right: 10),
child: const Text(
"驗證碼",
style: TextStyle(color: Color(0xFFA8A8A8), fontSize: 14),
),
),
Container(
height: 50,
width: 150,
child: TextFormField(
keyboardType: TextInputType.number,
style: const TextStyle(color: Colors.white),
controller: _AuthCodeController,
focusNode: _focusNodePassWord,
decoration: const InputDecoration(
//取消编辑框的下边框
border: OutlineInputBorder(borderSide: BorderSide.none),
hintText: "請輸入驗證碼",
hintStyle:
TextStyle(color: Color(0xFF54514C), fontSize: 14),
),
)),
Container(
padding: const EdgeInsets.only(
left: 9, right: 9, top: 6, bottom: 6),
decoration: BoxDecoration(
color: const Color(0xFF857D69),
borderRadius: BorderRadius.circular(50)),
child: GestureDetector(
onTap: () {
//弹窗
Navigator.push(
context, DialogRouter(LoadingDialog(true)));
sendAuthCode();
},
child: const Text(
"獲取驗證碼",
style: TextStyle(
fontSize: 10,
color: Color(0xFF252528),
fontWeight: FontWeight.bold),
),
),
)
],
),
Container(
margin: const EdgeInsets.only(bottom: 35),
height: 1,
decoration: const BoxDecoration(color: Color(0xFF3B3631)),
),
],
),
),
);
// “下一步”按钮区域,GestureDetector作用于整个Container
Widget nextStepButtonSection = GestureDetector(
//添加动作
onTap: () {
//点击下一步按钮,解除焦点,回收键盘
_focusNodePassWord.unfocus();
_focusNodePhone.unfocus();
//带参数跳转
Navigator.push(context,
MaterialPageRoute(builder: (BuildContext context) {
return ResetPasswordSubmit(
//手机号
userPhone: _userPhoneController.text,
//验证码
userCode: _AuthCodeController.text,
);
}));
},
child: Container(
margin: const EdgeInsets.only(left: 50, right: 50),
height: 45.0,
// 设置按钮圆角
decoration: BoxDecoration(
color: const Color(0x597C7C7C),
borderRadius: BorderRadius.circular(50.0)),
//用Center和textAlign:TextAlign.center使文字水平垂直居中
child: const Center(
child: Text(
"下一步",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black,
fontSize: 18,
fontWeight: FontWeight.bold),
),
),
));
return Material(
child: Scaffold(
appBar: AppBar(
//leading设置状态栏左边的图标
leading: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Container(
margin: const EdgeInsets.only(left: 10.0),
width: 20,
child: Image.asset(
'assets/base_widgets/icon_register_back.png',
fit: BoxFit.fitWidth,
),
),
),
title: const Text('重置密碼'),
backgroundColor: const Color(0xFF222222),
//文字居中
centerTitle: true,
),
body: Container(
//设置界面背景
decoration: const BoxDecoration(
color: Color(0xFF222222),
),
child: ListView(
children: <Widget>[
inputTextArea,
nextStepButtonSection,
],
),
)));
}
}
第二个界面如下
import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'LoginAccount.dart';
import 'data/AuthCode.dart';
//重置密码提交界面
//无状态组件用于跳转界面
// class ResetPasswordSubmitStateless extends StatelessWidget {
//
// const ResetPasswordSubmitStateless({key}) : super(key: key);
//
// @override
// Widget build(BuildContext context) {
// return const MaterialApp(home: ResetPasswordSubmit());
// }
// }
//有状态组件用来布置控件
class ResetPasswordSubmit extends StatefulWidget {
String userPhone;
String userCode;
ResetPasswordSubmit({key, this.userPhone, this.userCode}) : super(key: key);
@override
ResetPasswordSubmitState createState() => ResetPasswordSubmitState();
}
class ResetPasswordSubmitState extends State<ResetPasswordSubmit> {
//焦点
final FocusNode _focusNodeNewPassWord = FocusNode();
final FocusNode _focusNodeConfirmPassWord = FocusNode();
//输入框控制器
final TextEditingController _newPassWordController = TextEditingController();
final TextEditingController _confirmPassWardController =
TextEditingController();
//表单状态
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
@override
void initState() {
// TODO: implement initState
//设置焦点监听
_focusNodeNewPassWord.addListener(_focusNodeListener);
_focusNodeConfirmPassWord.addListener(_focusNodeListener);
print("${widget.userPhone}");
print("${widget.userCode}");
super.initState();
}
@override
void dispose() {
// TODO: implement dispose
// 移除焦点监听
_focusNodeNewPassWord.removeListener(_focusNodeListener);
_focusNodeConfirmPassWord.removeListener(_focusNodeListener);
super.dispose();
}
// 监听焦点
Future<Null> _focusNodeListener() async {
if (_focusNodeNewPassWord.hasFocus) {
// 取消新密码框的焦点状态
_focusNodeConfirmPassWord.unfocus();
}
if (_focusNodeConfirmPassWord.hasFocus) {
// 取消确认新密码框的焦点状态
_focusNodeNewPassWord.unfocus();
}
}
//发送验证码接口
reSetPassword() async {
var apiUrl = "http://47.242.63.216:9527/v1/user/resetPassword";
//参数
Map map = {};
//ID写死
map["app_id"] = "10001";
//短信类型 不填或0为注册验证码 1为重置密码验证码
map["auth_code"] = widget.userCode;
//密码
map["password"] = _newPassWordController.text;
//手机号
map["phone"] = widget.userPhone;
Response result = await Dio().post(apiUrl, data: map);
debugPrint("发送验证码接口返回${result}");
//json解析
Map<String, dynamic> authCode = json.decode(result.toString());
var mes = AuthCode.fromJson(authCode);
if (mes.code == 200) {
Fluttertoast.showToast(
msg: "${mes.msg}",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 10,
backgroundColor: Colors.white,
textColor: Colors.black,
fontSize: 16.0);
//回到登录界面
Navigator.pop(context);
Navigator.pop(context);
}
}
@override
Widget build(BuildContext context) {
//输入文本框区域
Widget inputTextArea = Container(
margin: const EdgeInsets.only(left: 60, right: 60, top: 70),
child: Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Row(
children: [
Container(
margin: const EdgeInsets.only(right: 10),
child: const Text(
"新密碼 ",
style: TextStyle(color: Color(0xFFA8A8A8), fontSize: 14),
),
),
SizedBox(
height: 50,
width: 150,
child: TextFormField(
style: TextStyle(color: Colors.white),
controller: _newPassWordController,
focusNode: _focusNodeNewPassWord,
//设置键盘类型
keyboardType: TextInputType.number,
decoration: const InputDecoration(
//取消编辑框的下边框
border: OutlineInputBorder(borderSide: BorderSide.none),
hintText: "鍵入8-20字符",
hintStyle:
TextStyle(color: Color(0xFF54514C), fontSize: 14),
),
),
),
],
),
//分割线
Container(
margin: const EdgeInsets.only(bottom: 26),
height: 1,
decoration: const BoxDecoration(color: Color(0xFF3B3631)),
),
//验证码那一行
Row(
children: [
Container(
margin: const EdgeInsets.only(right: 10),
child: const Text(
"確認新密碼",
style: TextStyle(color: Color(0xFFA8A8A8), fontSize: 14),
),
),
SizedBox(
height: 50,
width: 150,
child: TextFormField(
style: TextStyle(color: Colors.white),
keyboardType: TextInputType.number,
controller: _confirmPassWardController,
focusNode: _focusNodeConfirmPassWord,
decoration: const InputDecoration(
//取消编辑框的下边框
border: OutlineInputBorder(borderSide: BorderSide.none),
hintText: "鍵入你的密碼",
hintStyle:
TextStyle(color: Color(0xFF54514C), fontSize: 14),
),
)),
],
),
Container(
margin: const EdgeInsets.only(bottom: 35),
height: 1,
decoration: const BoxDecoration(color: Color(0xFF3B3631)),
),
],
),
),
);
// “提交”按钮区域
Widget submitStepButtonSection = GestureDetector(
//添加动作
onTap: () {
//点击提交按钮,解除焦点,回收键盘
_focusNodeConfirmPassWord.unfocus();
_focusNodeNewPassWord.unfocus();
//判断两个输入框的密码是否相同,相同就请求接口,不相同就吐司提醒
if (_newPassWordController.text == _confirmPassWardController.text) {
reSetPassword();
} else {
Fluttertoast.showToast(
msg: "密码不正确",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 10,
backgroundColor: Colors.white,
textColor: Colors.black,
fontSize: 16.0);
}
},
child: Container(
margin: const EdgeInsets.only(left: 50, right: 50),
height: 45.0,
// 设置按钮圆角
decoration: BoxDecoration(
color: const Color(0xFFD0B878),
borderRadius: BorderRadius.circular(50.0)),
//用Center和textAlign:TextAlign.center使文字水平垂直居中
child: const Center(
child: Text(
"提交",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black, fontSize: 18, fontWeight: FontWeight.bold),
),
),
),
);
return Material(
child: Scaffold(
appBar: AppBar(
//leading设置状态栏左边的图标
leading: GestureDetector(
onTap: (){
Navigator.pop(context);
},
child: Container(
margin: const EdgeInsets.only(left: 10.0),
width: 20,
child: Image.asset(
'assets/base_widgets/icon_register_back.png',
fit: BoxFit.fitWidth,
),
),
),
title: const Text('重置密碼'),
backgroundColor: const Color(0xFF222222),
//文字居中
centerTitle: true,
),
body: Container(
//设置界面背景
decoration: const BoxDecoration(
color: Color(0xFF222222),
),
child: ListView(
children: <Widget>[
inputTextArea,
submitStepButtonSection,
],
),
)));
}
}