Flutter 08: 图解【登录】页面小优化

作者: 阿策神奇 | 来源:发表于2018-08-20 22:50 被阅读116次

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


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

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

    2. 小菜查了一下官网,调整方式很简单,将根 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...

    键盘样式.png phone

    优化四:根据输入文本框添加【温馨提示】对话框

          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,还有很多不清楚和不理解的地方,如果又不对的地方还希望多多指出。以下是小菜公众号,欢迎闲来吐槽~

    公众号

    相关文章

      网友评论

      • 7c78a9d8ace3:博主:这有BUG啊.刚进来,点击输入用户名,弹出输入法软键盘,随便输入一些东西,直接点击清除按钮,这个时候输入用户名edit被清空,然后在次输入就崩了
        7c78a9d8ace3:@阿策神奇 刚进来,点击输入用户名,弹出输入法软键盘,随便输入一些东西,直接点击清除按钮,这个时候输入用户名edit被清空,注意:这里鼠标就不要乱点了.直接在次输入东西就可以
        7c78a9d8ace3:@阿策神奇 你操作的姿势不对吧.你按照我的不走操作,鼠标不要在空白处乱点.绝对蹦
        阿策神奇:@帅呆sky 老哥,吓着我了,我切换试了好久没有闪退啊,待会我更新一下GitHub:crying_cat_face:

      本文标题:Flutter 08: 图解【登录】页面小优化

      本文链接:https://www.haomeiwen.com/subject/vyuriftx.html