写点什么

【Flutter 专题】07 图解【登录】页面小优化

作者:阿策小和尚
  • 2021 年 11 月 16 日
  • 本文字数:5339 字

    阅读完需:约 18 分钟

【Flutter 专题】07 图解【登录】页面小优化

      小菜前两天花了很久才搭建了一个最简单的【登录】页面,但依然还有很多需要优化的地方,小菜又花了很久的时间尝试做了一点点的优化,仅针对优化的部分简单整理一下。


优化一:解决 OverFlowed 遮挡文本框问题

  1. 小菜刚开始在编辑内容块 content 时,以为涉及的 widget 元素不多,所占不会超过屏幕,所以根 widget 使用的是 body: new Container(),但是在点击文本框 TextField 时,弹出的键盘会挡住部分 widget,并提示 Bottom OverFlowed By 85 pixels,如图:

  1. 小菜查了一下官网,调整方式很简单,将根 widget 调整为 body: new ListView(),Flutter 中的 ListView 不仅代表列表 (ListView/RecycleView),还可以代表一个可滑动布局 (ScrollView),如图:


优化二:文本框 TextField 中尾部添加【清空数据】图标

方式一:使用层布局 Stack,在输入文本框 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: <Widget>[      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();        },      ),    ],  ),),
复制代码
方式二:使用文本框 TextField 自带的属性【后缀图标 suffixIcon】,文本框 TextField 提供了很多便利的属性,例如:【前缀图标 prefixIcon】【文本框前图标 icon】;
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<MyHomePage> { 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: <Widget>[ new Column( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[ 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: <Widget>[ 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<Null>( context: context, barrierDismissible: false, child: new AlertDialog( title: new Text( '温馨提示', style: new TextStyle( color: Colors.black54, fontSize: 18.0, ), ), content: new Text(_checkStr), actions: <Widget>[ new FlatButton( onPressed: () { Navigator.pop(context); }, child: new Text('确定')), ], ), ); }, ), ), ), ], ), ], ), ), ); }}
复制代码


      GitHub Demo


      小菜也是刚接触 Flutter,还有很多不清楚和不理解的地方,如果又不对的地方还希望多多指出。


来源:阿策小和尚

发布于: 3 小时前阅读数: 6
用户头像

还未添加个人签名 2021.05.13 加入

Android / Flutter 小菜鸟~

评论

发布
暂无评论
【Flutter 专题】07 图解【登录】页面小优化