小菜前两天花了很久才搭建了一个最简单的【登录】页面,但依然还有很多需要优化的地方,小菜又花了很久的时间尝试做了一点点的优化,仅针对优化的部分简单整理一下。
优化一:解决 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小时内删除侵权内容。