小菜前兩天花了很久才搭建了一個最簡單的【登錄】頁面,但依然還有很多需要優化的地方,小菜又花了很久的時間嘗試做了一點點的優化,僅針對優化的部分簡單整理一下。
優化一:解決 OverFlowed 遮擋文本框問題
小菜剛開始在編輯內容塊 content 時,以為涉及的 widget 元素不多,所占不會超過屏幕,所以根 widget 使用的是 body: new Container(),但是在點擊文本框 TextField 時,彈出的鍵盤會擋住部分 widget,并提示 Bottom OverFlowed By 85 pixels,如圖:
小菜查了一下官網,調整方式很簡單,將根 widget 調整為 body: new ListView(),flutter 中的 ListView 不僅代表列表 (ListView/RecycleView),還可以代表一個可滑動布局 (ScrollView),如圖:
優化二:文本框 TextField 中尾部添加【清空數據】圖標
new Padding( padding: new EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 15.0), child: new Stack( alignment: new Alignment(1.0, 1.0), //statck children: [ new Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ new Padding( padding: new EdgeInsets.fromLTRB(0.0, 0.0, 5.0, 0.0), child: new Image.asset( 'images/icon_username.png', width: 40.0, height: 40.0, fit: BoxFit.fill, ), ), new Expanded( child: new TextField( controller: _phonecontroller, keyboardType: TextInputType.phone, decoration: new InputDecoration( hintText: '請輸入用戶名', ), ), ), ]), new IconButton( icon: new Icon(Icons.clear, color: Colors.black45), onPressed: () { _phonecontroller.clear(); }, ), ], ), ),
new Expanded( child: new TextField( controller: _pwdcontroller, decoration: new InputDecoration( hintText: '請輸入密碼', suffixIcon: new IconButton( icon: new Icon(Icons.clear, color: Colors.black45), onPressed: () { _pwdcontroller.clear(); }, ), ), obscureText: true, ), ),
Tips: 小菜更傾向于方法二,方法一采用的是層布局,如果超過圖標所在位置,若不做特別處理,之后輸入的內容會被圖標擋住,而且相較于方法二使用了更多的 widget。小菜為了測試,在【輸入用戶名】模塊采用了方法一,【輸入密碼】模塊采用了方法二。
優化三:調整鍵盤彈出樣式
設置文本框 TextField 中 keyboardType: TextInputType.phone, flutter 提供了多種彈出鍵盤的方式:text/datetime/phone/url/number/multiline/emailAddress…
優化四:根據輸入文本框添加【溫馨提示】對話框

Flutter 提供了創建和顯示彈出對話框的功能,如:showDialog/showMenu/showModalBottomSheet 等,小菜采用的是對話框方式,可設置標題/內容/按鈕等各屬性。
Tips: 對話框中 barrierDismissible: false, 屬性,若為false,點擊對話框周圍,對話框不會關閉;若為true,點擊對話框周圍,對話框自動關閉。
相關注意
Flutter 提供了很多便利的小圖標,使用起來非常方便,小菜但就一個小【×】找到了好幾個類似的圖,希望可以多多嘗試,體驗一下。如圖:
主要源碼
import 'package:flutter/material.dart'; void main() => runApp(new MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: '輕簽到', theme: new ThemeData( primarySwatch: Colors.blue, ), home: new MyHomePage(title: '極速登錄'), ); } } class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => new _MyHomePageState(); } class _MyHomePageState extends State { bool _phoneState, _pwdState = false; String _checkStr; TextEditingController _phonecontroller = new TextEditingController(); TextEditingController _pwdcontroller = new TextEditingController(); void _checkPhone() { if (_phonecontroller.text.isNotEmpty && _phonecontroller.text.trim().length == 11) { _phoneState = true; } else { _phoneState = false; } } void _checkPwd() { if (_pwdcontroller.text.isNotEmpty && _pwdcontroller.text.trim().length >= 6 && _pwdcontroller.text.trim().length <= 10) { _pwdState = true; } else { _pwdState = false; } } @override Widget build(BuildContext context) { return new MaterialApp( title: '輕簽到', home: new Scaffold( appBar: new AppBar( title: new Text('極速登錄'), ), body: new ListView( children: [ new Column( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.start, children: [ new Padding( padding: new EdgeInsets.all(30.0), child: new Image.asset( 'images/ic_launcher.png', scale: 1.2, )), new Padding( padding: new EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 15.0), child: new Stack( alignment: new Alignment(1.0, 1.0), //statck children: [ new Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ new Padding( padding: new EdgeInsets.fromLTRB(0.0, 0.0, 5.0, 0.0), child: new Image.asset( 'images/icon_username.png', width: 40.0, height: 40.0, fit: BoxFit.fill, ), ), new Expanded( child: new TextField( controller: _phonecontroller, keyboardType: TextInputType.phone, decoration: new InputDecoration( hintText: '請輸入用戶名', ), ), ), ]), new IconButton( icon: new Icon(Icons.clear, color: Colors.black45), onPressed: () { _phonecontroller.clear(); }, ), ], ), ), new Padding( padding: new EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 40.0), child: new Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ new Padding( padding: new EdgeInsets.fromLTRB(0.0, 0.0, 5.0, 0.0), child: new Image.asset( 'images/icon_password.png', width: 40.0, height: 40.0, fit: BoxFit.fill, ), ), new Expanded( child: new TextField( controller: _pwdcontroller, decoration: new InputDecoration( hintText: '請輸入密碼', suffixIcon: new IconButton( icon: new Icon(Icons.clear, color: Colors.black45), onPressed: () { _pwdcontroller.clear(); }, ), ), obscureText: true, ), ), ]), ), new Container( width: 340.0, child: new Card( color: Colors.blue, elevation: 16.0, child: new FlatButton( child: new Padding( padding: new EdgeInsets.all(10.0), child: new Text( '極速登錄', style: new TextStyle( color: Colors.white, fontSize: 16.0), ), ), onPressed: () { _checkPhone(); _checkPwd(); if (_phoneState && _pwdState) { _checkStr = '頁面跳轉下期見咯!'; } else { if (!_phoneState) { _checkStr = '請輸入11位手機號!'; } else if (!_pwdState) { _checkStr = '請輸入6-10位密碼!'; } } print(_checkStr); showDialog( context: context, barrierDismissible: false, child: new AlertDialog( title: new Text( '溫馨提示', style: new TextStyle( color: Colors.black54, fontSize: 18.0, ), ), content: new Text(_checkStr), actions: [ new FlatButton( onPressed: () { Navigator.pop(context); }, child: new Text('確定')), ], ), ); }, ), ), ), ], ), ], ), ), ); } }
GitHub Demo
小菜也是剛接觸 Flutter,還有很多不清楚和不理解的地方,如果又不對的地方還希望多多指出。
來源:阿策小和尚
Flutter
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。