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

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

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


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

公众号

目录
相关文章
|
10月前
|
缓存 监控 前端开发
【Flutter 前端技术开发专栏】Flutter 应用的启动优化策略
【4月更文挑战第30天】本文探讨了Flutter应用启动优化策略,包括理解启动过程、资源加载优化、减少初始化工作、界面布局简化、异步初始化、预加载关键数据、性能监控分析以及案例和未来优化方向。通过这些方法,可以缩短启动时间,提升用户体验。使用Flutter DevTools等工具可助于识别和解决性能瓶颈,实现持续优化。
333 0
【Flutter 前端技术开发专栏】Flutter 应用的启动优化策略
|
10月前
|
JSON Dart 安全
Flutter App混淆加固、保护与优化原理
Flutter App混淆加固、保护与优化原理
175 0
|
存储 JSON 数据库
Flutter必备技能:轻松掌握本地存储与数据库优化技巧!
Flutter必备技能:轻松掌握本地存储与数据库优化技巧!
200 0
|
1月前
|
前端开发 安全 开发工具
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
188 90
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
2月前
|
Dart 前端开发
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
133 75
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
2月前
|
Dart 前端开发 容器
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
107 18
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
2月前
|
缓存 前端开发 Android开发
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
134 12
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
|
2月前
|
缓存 前端开发 IDE
【06】flutter完成注册页面-密码登录-手机短信验证-找回密码相关页面-并且实现静态跳转打包demo做演示-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【06】flutter完成注册页面-密码登录-手机短信验证-找回密码相关页面-并且实现静态跳转打包demo做演示-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
42 0
【06】flutter完成注册页面-密码登录-手机短信验证-找回密码相关页面-并且实现静态跳转打包demo做演示-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
4月前
|
缓存 前端开发 数据安全/隐私保护
Flutter 框架提供了丰富的机制和方法来优化键盘处理和输入框体验
在移动应用开发中,Flutter 框架提供了丰富的机制和方法来优化键盘处理和输入框体验。本文深入探讨了键盘的显示与隐藏、输入框的焦点管理、键盘类型的适配、输入框高度自适应、键盘遮挡问题处理及性能优化等关键技术,结合实例分析,旨在帮助开发者提升应用的用户体验。
164 6
|
4月前
|
存储 缓存 Dart
Flutter&鸿蒙next 封装 Dio 网络请求详解:登录身份验证与免登录缓存
本文详细介绍了如何在 Flutter 中使用 Dio 封装网络请求,实现用户登录身份验证及免登录缓存功能。首先在 `pubspec.yaml` 中添加 Dio 和 `shared_preferences` 依赖,然后创建 `NetworkService` 类封装 Dio 的功能,包括请求拦截、响应拦截、Token 存储和登录请求。最后,通过一个登录界面示例展示了如何在实际应用中使用 `NetworkService` 进行身份验证。希望本文能帮助你在 Flutter 中更好地处理网络请求和用户认证。
254 1

热门文章

最新文章

  • 1
    【Flutter 开发必备】AzListView 组件全解析,打造丝滑索引列表!
    40
  • 2
    flutter3-wetrip跨平台自研仿携程app预约酒店系统模板
    40
  • 3
    通过外部链接启动 Flutter App(详细介绍及示例)
    39
  • 4
    【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
    213
  • 5
    零基础构建即时通讯开源项目OpenIM移动端-Flutter篇
    110
  • 6
    flutter3-dart3-dymall原创仿抖音(直播+短视频+聊天)商城app系统模板
    77
  • 7
    【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    188
  • 8
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    62
  • 9
    当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
    89
  • 10
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    190