Flutter教程:註冊頁面

完成結果如下圖:


Flutter教程:註冊頁面

image.png

完整代碼如下:

<code>import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_app2/utils/validator.dart';
class Register extends StatefulWidget{
@override
_RegisterState createState()=> _RegisterState();
}
class _RegisterState extends State<register> {
TextEditingController _mobile = TextEditingController();
TextEditingController _veriCode = TextEditingController();
FocusNode _mobileFocus = FocusNode();
FocusNode _veriFocus = FocusNode();
Timer _timer;
int _start = 60;
void countdown(){
const oneSec = const Duration(seconds: 1);
_timer = new Timer.periodic(
oneSec,
(Timer timer) => setState(
() {
if (_start < 1) {
timer.cancel();//定時器清除
_start = 60;
} else {
_start = _start - 1;
}
},
),
);
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar:AppBar( title: Text("登錄"), ),
body: Container(
width: double.infinity,
height: MediaQuery.of(context).size.height * 0.67,
color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,

children: <widget>[
Center(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Image.asset(
"imgs/logoImg.png",
width: ScreenUtil().setWidth(444),
height: ScreenUtil().setHeight(384),
),
),
),
Container(
width: ScreenUtil().setWidth(710),
height: ScreenUtil().setHeight(90),
decoration: BoxDecoration(
color: Color(0xFFF2F2F2),
),
child: Row(
children: <widget>[
Container(
width: ScreenUtil().setWidth(160),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <widget>[
Text("+86", style: TextStyle(
fontSize: ScreenUtil().setSp(28.0)
),),
Icon(
Icons.arrow_drop_down,
size: 30.0,
)
],
),
),
Expanded(
child: TextFormField(
focusNode: _mobileFocus,
keyboardType: TextInputType.phone,
decoration: const InputDecoration(
hintText: '請輸入手機號',
border: InputBorder.none,
),
controller: _mobile,
),
)
],
)
),
Container(
margin: EdgeInsets.only(top: ScreenUtil().setHeight(20.0) ),

width: ScreenUtil().setWidth(710),
height: ScreenUtil().setHeight(90),
child: Row(
children: <widget>[
Container(
decoration: BoxDecoration(
color: Color(0xFFF2F2F2),
),
width: ScreenUtil().setWidth(444),
height: ScreenUtil().setWidth(90),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <widget>[
Container(
width: ScreenUtil().setWidth(160),
child: Center(
child: Text("驗證碼", style: TextStyle(
fontSize: ScreenUtil().setSp(28.0),
)),
),
),
Expanded(
child: TextFormField(
focusNode: _veriFocus,
controller: _veriCode,
keyboardType: TextInputType.number,
decoration: const InputDecoration(
hintText: "請輸入驗證碼",
border: InputBorder.none,
),
validator: (value) {
if (value.isEmpty) {
return 'Please enter some text';
}
return null;
},
),
)
],
),
),
Expanded(
child: Padding(
padding: EdgeInsets.only(left: 15.0),
child: Builder(builder:(BuildContext context){
return FlatButton(
onPressed: (){
_mobileFocus.unfocus();
if(_start != 60){ //簡單判斷是否可以觸發獲取驗證

return null;
}
var result = Validator.checkMobile(this._mobile.text); //驗證手機號
if(result == true){
print("驗證通過");
countdown();
}else{
Scaffold.of(context).hideCurrentSnackBar();
Scaffold.of(context).showSnackBar(
SnackBar(
duration : Duration(seconds: 1),
backgroundColor: Colors.orangeAccent,
content: new Text(result)
)
);
}
},
color: _start==60 ? Colors.blue : Colors.grey,
textColor: _start==60 ? Colors.white : Colors.black54,
child:Container(
height:ScreenUtil().setHeight(80),
child: Center(
child: Text(
_start == 60 ? "獲取驗證碼" : "${_start} S"
),
),
)
);
})
)
)
],
)
),
Container(
padding: EdgeInsets.only(
left: ScreenUtil().setWidth(20),
top: ScreenUtil().setHeight(20),
bottom: ScreenUtil().setHeight(80),
),
child: Align(
alignment: Alignment.centerLeft,
child: Text(
"請輸入您的手機號碼,註冊您的賬號",
style:TextStyle(
fontSize: ScreenUtil().setSp(28.0)
),

),
),
),
Container(
margin: EdgeInsets.only(top: ScreenUtil().setHeight(20.0)),
width: ScreenUtil().setWidth(710),
height: ScreenUtil().setHeight(90),
child:Builder(builder: (context){
return FlatButton(
color: Colors.blue,
textColor: Colors.white,
onPressed: () async {
_veriFocus.unfocus();
_mobileFocus.unfocus();
Scaffold.of(context).hideCurrentSnackBar();
Scaffold.of(context).showSnackBar(
SnackBar(
duration : Duration(seconds: 1),
backgroundColor: Colors.green,
content: new Text("註冊成功")
)
);
},
child: Container(
width: ScreenUtil().setWidth(710),
height: ScreenUtil().setHeight(90),
child: Center(
child:Text(
"註冊",
style: TextStyle(
fontSize: ScreenUtil().setSp(28.0)
),
),
),
),
);
})
),
],
)
),
resizeToAvoidBottomPadding:false
);
}
@override
void dispose() { //定時器清除
_timer?.cancel();
super.dispose();
}

}
/<widget>/<widget>/<widget>/<widget>/<widget>/<register>/<code>


Flutter教程:註冊頁面

image.png

驗證器文件:

<code>class Validator {
static checkMobile(value){
if(value.isEmpty){
return "請輸入手機號";
}
RegExp reg = new RegExp(r'^\\d{11}$');
if (!reg.hasMatch(value)) {
return "請輸入11位手機號碼";
}
return true;
}
}
/<code>

踩坑點: 1.文本框獲得焦點,頁面溢出問題,我這個頁面,採用一種討巧方式解決。解決:設置Scaffold屬性resizeToAvoidBottomPadding:false 2.Scaffold.of(context).showSnackBar()一直報context沒有Scaffold錯誤。解決:採用Builder組件,傳遞context 3.Scaffold.of(context).showSnackBar()多次點擊,隊列展示而不是顯示最新一個。解決: 調用展示之前,手動清除Scaffold.of(context).hideCurrentSnackBar(); 4.按照網上的例子寫了一個文本值獲取,結果光標亂跳。網上的例子沒理解TextFormField的controller會自動存值。

學到的點: 1.Dart計時器 2.Dart頁面條件渲染 3.Dart驗證器編寫(包含正則語法)


分享到:


相關文章: