上一篇文章Flutter系列:1.開發環境配置已經配置好了基本的開發環境,那麼這篇將直入主題,實現一個簡單的登陸頁面,實現輸入用戶名密碼點擊登陸後驗證輸入有效性,模擬調用api登陸,最終彈窗提示登陸成功。git
tips: 在開始前,你應該快速瞭解下dart的 基本語法
本示例算是一個比較常見的簡單app頁面,包括頂部的一個導航欄及其title, 而後一個白底的頁面,從上到下依次是一個圖片顯示控件,用戶名和密碼的文本輸入控件,以及一個提交的按鈕。github
在開始Flutter佈局前,心中應該始終記住一個概念,那就是在Flutter佈局中顯示的都是Widget,包括看得見頁面、圖片、輸入框、按鈕...其餘看不見的列布局控件('Column'), 容器佈局控件('Container')、('SizedBox'),用戶表單顯示的控件('Form') 甚至用做填充的控件('Padding'), 居中的控件('Center');segmentfault
void main() { debugPaintSizeEnabled = false; runApp(new LoginAlertDemoApp()); } class LoginAlertDemoApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return new MaterialApp( title: 'Login Alert', theme: new ThemeData( primarySwatch: Colors.blue, ), home: Scaffold( appBar: AppBar( title: Text('Login Alert'), ), body: new LoginHomePage(), )); } }
main函數顧名思義,就是app運行的入口,debugPaintSizeEnabled是用戶調試顯示的;而後是調用sdk的runApp方法,傳入一個Widget對象並將它顯示到屏幕上,因此此Widget即是APP顯示的基礎Widget,有點至關於iOS開發中的rootViewController來負責承載整個APP的顯示。api
在此示例中傳入runApp方法的這個Widget是LoginAlertDemoApp,繼承自StatelessWidget;重寫了其build方法建立了一個MaterialApp的Widget。也就是說主要負責顯示的就是MaterialApp的對象,它是用於實現谷歌設計的一套material design設計風格的基礎顯示Widget,封裝了一系列的經常使用組件和導航控制,好比主題控制。從代碼能夠看到其home屬性是一個Scaffold對象,Scaffold也是material design的基礎組件之一,實現基本頁面佈局結構,好比頁面導航欄,同時也封裝了一系列的基礎控件,好比'抽屜頁',toast提示,底部sheet提示。基於material design風格的app基本上都是構建在這2個基礎控件之上的。網絡
接下來就是咱們本身實現的頁面佈局了,LoginHomePage繼承自StatefulWidget,注意到Widget有StatefulWidget和StatelessWidget之分,簡單的理解呢就是StatefulWidget是具備可變狀態的Widget,
它須要一個State來保存其生命週期中的一些狀態數據,並在數據改變時經過setState通知到Widget及時更新。而StatelessWidget則是無狀態的,不須要維護其狀態,只是簡單的顯示。app
因此咱們須要_LoginHomePageState來維護LoginHomePage生命週期中的一些狀態變化數據,並經過build方法來實時構建LoginHomePage的顯示Widget。less
頁面分析這是一個簡單的表單提交頁面,可使用'Form'來進行佈局,同時也能很方便經過其State屬性的validate()方法來實現輸入驗證和提示。
validate()會調用TextFormField的validator來執行驗證。異步
用於顯示圖片的,支持網絡圖片和本地圖片,本地圖片須要添加到配置文件中async
# To add assets to your application, add an assets section, like this: # assets: # - images/a_dot_burr.jpeg # - images/a_dot_ham.jpeg assets: - images/lake.jpg
Form中對應的文本輸入控件,validator用於驗證輸入的合法性,當驗證不經過時返回一個字符串提示在輸入框的底部。ide
按鈕,沒什麼好說的,onPressed指定點擊回調
列布局,此demo中各控件從上到下依次佈局,Column再合適不過了。
調用AlertDialog顯示一個文本的Widget。
此demo中使用了一個第三方的加載提示組件flutter_spinkit
main.dart頂部代碼
import 'package:flutter_spinkit/flutter_spinkit.dart';
這是引入的一個第三方加載提示組件flutter_spinkit,使用第三方組件前須要先到pubspec.yaml文件添加依賴配置:
flutter_spinkit: "^2.1.0"
保存後VSCode會自動執行'flutter packages get'下載組件。
使用代碼:
final _loadingContainer = Container( constraints: BoxConstraints.expand(), color: Colors.black12, child: Center( child: Opacity( opacity: 0.9, child: SpinKitWave( color: Colors.red, size: 50.0, ), ), ) );
點擊按鈕後執行的是如下代碼:
void _toggleSubmit() { if (_formKey.currentState.validate()) { setState(() { _showLoading = true; }); _loginRequest().then((onValue) { setState(() { _showLoading = false; }); showDialog( context: context, builder: (context) { String alertText = 'login success!' + ' \nuserName:' + _userNameTextController.text + '\npassWord:' + _passwordTextController.text; return AlertDialog( content: Text(alertText), ); }); }); } }
首先經過預先指定的GlobalKey的currentState來拿到對應的FormState, 而後調用validate()方法執行驗證Form中的用戶名和密碼輸入內容,經過返回true,不然返回false; 而後經過setState()方法來更新_showLoading屬性爲true或者false, 便會從新執行build方法,這樣就能夠動態的顯示和隱藏加載框了。
異步操做
Future _loginRequest() async { return Future.delayed(Duration(seconds: 3), () { //do nothing print('login success'); }); }
_loginRequest函數返回的是一個Future, 用於dart支持異步操做的關鍵字,顧名思義這個函數調用後會在將來執行而不是馬上執行,更多細節推薦閱讀flutter實戰5:異步async、await和Future的使用技巧。
在_loginRequest函數中,這裏只是簡單的執行延遲3秒操做來模擬api調用耗時,點擊submit按鈕後調用此方法,此方法執行完成後調用then方法使用setState來隱藏加載框,同時彈出提示框顯示獲取到的用戶名和密碼。
_loginRequest().then((onValue) { setState(() { _showLoading = false; }); showDialog( context: context, builder: (context) { String alertText = 'login success!' + ' \nuserName:' + _userNameTextController.text + '\npassWord:' + _passwordTextController.text; return AlertDialog( content: Text(alertText), ); }); });
嗯,到此就差很少了,該準備下一個學習demo了,後續Demo持續更新...