为了账号安全,请及时绑定邮箱和手机立即绑定

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

标签:
Android

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


webp

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

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

    webp


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

    webp


优化二:文本框 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...

webp

键盘样式.png

webp

phone

webp

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

      Flutter 提供了创建和显示弹出对话框的功能,如:showDialog/showMenu/showModalBottomSheet 等,小菜采用的是对话框方式,可设置标题/内容/按钮等各属性。
      Tips: 对话框中 barrierDismissible: false, 属性,若为false,点击对话框周围,对话框不会关闭;若为true,点击对话框周围,对话框自动关闭。

webp

webp

webp

相关注意

      Flutter 提供了很多便利的小图标,使用起来非常方便,小菜但就一个小【×】找到了好几个类似的图,希望可以多多尝试,体验一下。如图:

webp

主要源码

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('确定')),
                            ],
                          ),
                        );
                      },
                    ),
                  ),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}



作者:阿策神奇


点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
移动开发工程师
手记
粉丝
165
获赞与收藏
165

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消