Flutter 登入頁面
阿新 • • 發佈:2020-09-09
Flutter 一個漂亮的登入頁面
專案地址: https://github.com/whiskyma/flutter_demo_login
flutter-demo-login 快速構建Flutter專案基礎模板搭建,並完成登入頁製作.
所需元件如下:
元件 |
名稱 |
連結 |
底部導航切換 | bottomNavigationBar | https://book.flutterchina.club/chapter5/material_scaffold.html |
抽屜選單 | Drawer | https://book.flutterchina.club/chapter5/material_scaffold.html |
Hero動畫 | Hero | https://book.flutterchina.club/chapter9/hero.html |
Loadding動畫 | flutter_spinkit | https://pub.dev/packages/flutter_spinkit |
Toast提示 | Toast | https://pub.dev/packages/toast |
.... | ... | .... |
登入頁效果圖(效驗正則,按鈕禁用和登入loadding狀態顯示):
設定和註冊頁:
各個路由元件:
main.dart程式碼如下:
import 'package:flutter/material.dart'; import './router/index.dart'; import 'dart:io'; import 'package:flutter/services.dart'; void main() { runApp(new MyApp()); if(Platform.isAndroid){ // 設定狀態列背景及顏色 SystemUiOverlayStyle systemUiOverlayStyle = SystemUiOverlayStyle(statusBarColor: Colors.transparent); SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle); } } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: '登入Demo', debugShowCheckedModeBanner: false, routes: routes, ); } }
login.dart程式碼如下:
import 'package:flutter/material.dart'; import '../components/common/toast.dart'; import '../components/common/loadding.dart'; class Login extends StatefulWidget{ @override _LoginState createState() => new _LoginState(); } class _LoginState extends State<Login>{ // 控制器 final _unameController = TextEditingController(); final _pwdController = TextEditingController(); final _formKey = GlobalKey<FormState>(); // 焦點 final focusNode1 = FocusNode(); final focusNode2 = FocusNode(); bool isEye = true; bool isBtnEnabled = false; bool showLoading = false; final _unameExp = RegExp(r'^(?![0-9]+$)(?![a-z]+$)[0-9a-z]{6,12}$'); //使用者名稱正則 final _pwdExp = RegExp(r'^(?![0-9]+$)(?![a-z]+$)[0-9a-z]{6,12}$'); //密碼正則 // 登入按鈕是否可點選 void checkLoginText(){ if(_unameExp.hasMatch(_unameController.text)&&_pwdExp.hasMatch(_pwdController.text)){ this.isBtnEnabled = true; }else{ this.isBtnEnabled = false; } } // 登入提交 void loginSub(){ FocusScope.of(context).requestFocus(FocusNode()); //收起鍵盤 setState((){ this.showLoading = true; }); loginRequest().then((v) => { setState((){ this.showLoading = false; }), // toast提示 // 模擬登入跳轉首頁 ToastCom.show('登入成功', context), Navigator.pushNamed(context, '/') // showDialog( // context: context, // builder: (context){ // String alertText = "登入成功!!!"+"\n使用者名稱:"+_unameController.text+"\n密碼:"+_pwdController.text; // return AlertDialog(content: Text(alertText)); // } // ) }); } @override void initState(){ super.initState(); } @override void dispose(){ super.dispose(); } // 非同步操作 Future loginRequest() async { return Future.delayed(Duration(seconds: 3),(){ print('login success'); }); } @override Widget build(BuildContext context){ List<Widget> childrens = []; final _main = Center( child: ListView( padding: EdgeInsets.only(left: 30.0, right: 30.0,top: 70.0), children: [ Padding( padding: EdgeInsets.only(bottom: 40), child: Hero( tag: 'avatar', child: CircleAvatar( backgroundColor: Colors.transparent, radius: 50.0, child: Image.asset('assets/images/avatar.png'), ), ), ), Form( key: _formKey, autovalidate: true, child: Column( children: [ TextFormField( //使用者名稱 controller: _unameController, focusNode: focusNode1,//關聯focusNode1 keyboardType: TextInputType.text,//鍵盤型別 maxLength: 12, textInputAction: TextInputAction.next,//顯示'下一步' decoration: InputDecoration( hintText: '請輸入賬號', labelText: "賬號", contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0), prefixIcon:Icon(Icons.perm_identity), border: OutlineInputBorder( borderRadius: BorderRadius.circular(40.0) //圓角大小 ), suffixIcon: _unameController.text.length>0?IconButton( icon: Icon( Icons.clear, size: 21, color: Color(0xff666666), ), onPressed: (){ setState(() { _unameController.text = ''; checkLoginText(); }); }, ):null ), validator: (v) { return !_unameExp.hasMatch(v)?'賬號由6到12位數字與小寫字母組成':null; }, onEditingComplete: ()=>FocusScope.of(context).requestFocus(focusNode2), onChanged: (v){ setState(() { checkLoginText(); }); }, ), SizedBox(height: 15.0), TextFormField( //密碼 controller: _pwdController, focusNode: focusNode2,//關聯focusNode1 obscureText: isEye, //密碼型別 內容用***顯示 maxLength: 12, textInputAction: TextInputAction.done, //顯示'完成' decoration: InputDecoration( hintText: '請輸入密碼', labelText: '密碼', contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0), prefixIcon:Icon(Icons.lock), border: OutlineInputBorder( borderRadius: BorderRadius.circular(40.0) ), suffixIcon: IconButton( icon: Icon( Icons.remove_red_eye, size: 21, color: Color(0xff666666), ), onPressed: (){ setState(() { isEye = !isEye; }); }, ) ), validator:(v){ return !_pwdExp.hasMatch(v)?'密碼由6到12位數字與小寫字母組成':null; }, onChanged: (v){ setState(() { checkLoginText(); }); }, onEditingComplete: ()=>loginSub(), //'完成'回撥 ) ], ), ), Padding( padding: EdgeInsets.symmetric(vertical: 5.0), child: RaisedButton( color: const Color(0xff2a8fbd), padding: EdgeInsets.symmetric(vertical: 10.0), // splashColor: const Color(0xffde19de),//水波紋顏色 disabledColor: const Color(0xff999999), shape:RoundedRectangleBorder(borderRadius: BorderRadius.circular(60.0)),//圓角 child: Text('登入',style: TextStyle(fontSize: 18.0, color: Colors.white)), onPressed: !isBtnEnabled?null:loginSub, ), ), FlatButton( child: Text('忘記密碼?', style: TextStyle(color: Colors.black54,fontSize: 15.0)), onPressed: () { Navigator.pushNamed(context, 'forget'); }, ), ], ), ); childrens.add(_main); if(this.showLoading){ childrens.add(Loadding()); } return Scaffold( appBar: AppBar( iconTheme: IconThemeData(color: Colors.white), centerTitle: true, title: Text('登入',style: TextStyle(color: Colors.white)), ), body: Stack(children: childrens), ); } }
專案地址: https://github.com/whiskyma/flutter_demo_login
最後,如果大家覺得此專案程式碼對你點幫助,記得給我點贊哦!!!後續會不斷的更新專案程式碼,繼續的完成其他功能!!!
大家如果遇到什麼問題,評論區見!!!
相互學習,相互進步,記得點贊,謝謝!!!