34 Flutter仿京东商城项目 用户注册 注册流程 POST发送验证码 倒计时功能 验证验证码
加群452892873 下载对应34课文件,运行方法,建好项目,直接替换lib目录
以下列出的是本课涉及的文件。
RegisterFirst.dart
import 'package:flutter/material.dart'; import 'package:flutter_jdshop/services/ScreenAdapter.dart'; import 'package:flutter_jdshop/widget/JdButton.dart'; import 'package:flutter_jdshop/widget/JdText.dart'; import '../config/Config.dart'; import 'package:dio/dio.dart'; import 'package:fluttertoast/fluttertoast.dart'; class RegisterFirstPage extends StatefulWidget { RegisterFirstPage({Key key}) : super(key: key); _RegisterFirstPageState createState() => _RegisterFirstPageState(); } class _RegisterFirstPageState extends State<RegisterFirstPage> { String tel; sendCode() async{ RegExp reg=new RegExp(r"^1\d{10}$"); if(reg.hasMatch(this.tel)){ print("正确"); var api='${Config.domain}api/sendCode'; var responses=await Dio().post(api,data:{"tel":this.tel}); if(responses.data["success"]){ print(responses); //演示期间服务器直接返回给手机发送的验证码 Navigator.pushNamed(context, '/RegisterSecond',arguments: { "tel":this.tel }); }else{ Fluttertoast.showToast( msg: "${responses.data["message"]}", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.CENTER, ); } }else{ Fluttertoast.showToast( msg: "手机号格式不对", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.CENTER, ); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('用户注册-第一步'), ), body: Container( padding: EdgeInsets.all(ScreenAdapter.width(20)), child: ListView( children: <Widget>[ SizedBox(height: 20), JdText( text: "请输入手机号", // password: true, onChanged: (value) { this.tel=value; // print(value); }, ), SizedBox(height: 20), JdButton( text: "下一步", color: Colors.red, cb:sendCode ) ], ), ), ); } }
RegisterSecond.dart
import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:flutter_jdshop/config/Config.dart'; import 'package:flutter_jdshop/services/ScreenAdapter.dart'; import 'package:flutter_jdshop/widget/JdButton.dart'; import 'package:flutter_jdshop/widget/JdText.dart'; import 'dart:async'; import 'package:fluttertoast/fluttertoast.dart'; class RegisterSecondPage extends StatefulWidget { Map arguments; RegisterSecondPage({Key key, this.arguments}) : super(key: key); _RegisterSecondPageState createState() => _RegisterSecondPageState(); } class _RegisterSecondPageState extends State<RegisterSecondPage> { String tel; bool sendCodeBtn = false; int seconds = 10; String code; @override void initState() { super.initState(); this.tel = widget.arguments["tel"]; this._showTimer(); } // _showTimer() { print("执行倒计时"); print(this.sendCodeBtn); Timer t; t = Timer.periodic(Duration(microseconds: 1000), (timer) { setState(() { this.seconds--; }); if (this.seconds == 0) { t.cancel(); //清除定时器: setState(() { this.sendCodeBtn = true; }); } }); } //重新发送验证码: sendCode() async { setState(() { this.sendCodeBtn = false; this.seconds = 10; this._showTimer(); }); var api = '${Config.domain}api/sendCode'; var responses = await Dio().post(api, data: {"tel": this.tel}); if (responses.data["success"]) { print(responses); //演示期间服务器直接返回给手机发送的验证码 print(this.sendCodeBtn); } else { Fluttertoast.showToast( msg: "${responses.data["message"]}", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.CENTER, ); } } validateCode() async { var api = '${Config.domain}api/validateCode'; var responses = await Dio().post(api, data: {"tel": this.tel, "code": this.code}); if (responses.data["success"]) { print(responses); Navigator.pushNamed(context, '/RegisterThird'); } else { Fluttertoast.showToast( msg: "${responses.data["message"]}", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.CENTER, ); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('用户注册-第二步'), ), body: Container( padding: EdgeInsets.all(ScreenAdapter.width(20)), child: ListView( children: <Widget>[ Container( margin: EdgeInsets.all(20), child: Text("请输入${this.tel}手机收到的验证码"), ), Stack( children: <Widget>[ JdText( text: "请输入验证码", // password: true, onChanged: (value) { print(value); this.code = value; }, ), Positioned( right: 0, top: 0, child: this.sendCodeBtn? RaisedButton( child: Text("重新${this.sendCodeBtn}发送"), onPressed: this.sendCode, ): RaisedButton( child: Text('${this.seconds}秒后重发'), onPressed: () {}, ), ) ], ), SizedBox(height: 20), JdButton( text: "下一步", color: Colors.red, cb: validateCode, ) ], ), ), ); } }
import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:flutter_jdshop/config/Config.dart'; import 'package:flutter_jdshop/services/ScreenAdapter.dart'; import 'package:flutter_jdshop/widget/JdButton.dart'; import 'package:flutter_jdshop/widget/JdText.dart'; import 'dart:async'; import 'package:fluttertoast/fluttertoast.dart'; class RegisterSecondPage extends StatefulWidget { Map arguments; RegisterSecondPage({Key key, this.arguments}) : super(key: key); _RegisterSecondPageState createState() => _RegisterSecondPageState(); } class _RegisterSecondPageState extends State<RegisterSecondPage> { String tel; bool sendCodeBtn = false; int seconds = 10; String code; @override void initState() { super.initState(); this.tel = widget.arguments["tel"]; this._showTimer(); } // _showTimer() { print("执行倒计时"); print(this.sendCodeBtn); Timer t; t = Timer.periodic(Duration(microseconds: 1000), (timer) { setState(() { this.seconds--; }); if (this.seconds == 0) { t.cancel(); //清除定时器: setState(() { this.sendCodeBtn = true; }); } }); } //重新发送验证码: sendCode() async { setState(() { this.sendCodeBtn = false; this.seconds = 10; this._showTimer(); }); var api = '${Config.domain}api/sendCode'; var responses = await Dio().post(api, data: {"tel": this.tel}); if (responses.data["success"]) { print(responses); //演示期间服务器直接返回给手机发送的验证码 print(this.sendCodeBtn); } else { Fluttertoast.showToast( msg: "${responses.data["message"]}", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.CENTER, ); } } validateCode() async { var api = '${Config.domain}api/validateCode'; var responses = await Dio().post(api, data: {"tel": this.tel, "code": this.code}); if (responses.data["success"]) { print(responses); Navigator.pushNamed(context, '/RegisterThird'); } else { Fluttertoast.showToast( msg: "${responses.data["message"]}", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.CENTER, ); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('用户注册-第二步'), ), body: Container( padding: EdgeInsets.all(ScreenAdapter.width(20)), child: ListView( children: <Widget>[ Container( margin: EdgeInsets.all(20), child: Text("请输入${this.tel}手机收到的验证码"), ), Stack( children: <Widget>[ JdText( text: "请输入验证码", // password: true, onChanged: (value) { print(value); this.code = value; }, ), Positioned( right: 0, top: 0, child: this.sendCodeBtn? RaisedButton( child: Text("重新${this.sendCodeBtn}发送"), onPressed: this.sendCode, ): RaisedButton( child: Text('${this.seconds}秒后重发'), onPressed: () {}, ), ) ], ), SizedBox(height: 20), JdButton( text: "下一步", color: Colors.red, cb: validateCode, ) ], ), ), ); } }
router.dart
import 'package:flutter/material.dart'; import 'package:flutter_jdshop/pages/Login.dart'; import 'package:flutter_jdshop/pages/RegisterFirst.dart'; import 'package:flutter_jdshop/pages/RegisterSecond.dart'; import 'package:flutter_jdshop/pages/RegisterThird.dart'; import 'package:flutter_jdshop/pages/tabs/Cart.dart'; import '../pages/tabs/Tabs.dart'; import '../pages/Search.dart'; import '../pages/ProductList.dart'; import '../pages/ProductContent.dart'; //配置路由 final routes = { '/': (context) => Tabs(), '/login': (context) => LoginPage(), '/RegisterFirst': (context) =>RegisterFirstPage(), '/RegisterSecond': (context,{arguments}) =>RegisterSecondPage(arguments:arguments), '/RegisterThird': (context) =>RegisterThirdPage(), '/search': (context) => SearchPage(), '/cart': (context) => CartPage(), '/productList': (context,{arguments}) => ProductListPage(arguments:arguments), '/productContent': (context,{arguments}) => ProductContentPage(arguments:arguments), }; //固定写法 var onGenerateRoute = (RouteSettings settings) { // 统一处理 final String name = settings.name; final Function pageContentBuilder = routes[name]; if (pageContentBuilder != null) { if (settings.arguments != null) { final Route route = MaterialPageRoute( builder: (context) => pageContentBuilder(context, arguments: settings.arguments)); return route; } else { final Route route = MaterialPageRoute(builder: (context) => pageContentBuilder(context)); return route; } } };