Flutter 实现一个登录界面

更新日期: 2019-08-14阅读: 3k标签: 界面

初入flutter,在 flutter中文网 ,学习了两天flutter基本内容。做一个登录界面与大家分享学习。文中有不对的地方,还望不吝赐教!

1、先看下整个界面

布局方式在flutter中还是比较简单。先看整体,然后再拆分一个个小块即可。也就是将每个小块做成 flutter 中widget ,最后在整合到一起。


主要实现内容,涉及到基础知识点有:

1.头部logo图片,导入读取运用。

2.TextFormField文本框内容,并且验证用户名、密码。TextEditingController,监听用户名文本框,并在末尾显示清除按钮。显示和隐藏密码。FocusNode 控制焦点内容,实现键盘回收。

3.按钮,RaisedButton、IconButton、FlatButton的使用。

4.通过添加手势(GestureDetector),实现点击空白处,键盘回收操作。

5.第三方插件使用,【flutter_screenutil: ^0.4.2 (屏幕适配插件)和 font_awesome_flutter: ^8.2.0 (第三方 icon 图标插件)】

6.分区块实现每个widget,最后将各个区块widget,放到ListView组件中。代码中SizedBox为占位作用,也可以替换成其他内容。

全部实现代码如下:

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
class LoginPage extends StatefulWidget {
  @override
  _LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State {
  //焦点
  FocusNode _focusNodeUserName = new FocusNode();
  FocusNode _focusNodePassWord = new FocusNode();
  //用户名输入框控制器,此控制器可以监听用户名输入框操作
  TextEditingController _userNameController = new TextEditingController();
  //表单状态
  GlobalKey _formKey = GlobalKey();
  var _password = '';//用户名
  var _username = '';//密码
  var _isShowPwd = false;//是否显示密码
  var _isShowClear = false;//是否显示输入框尾部的清除按钮
  @override
  void initState() {
    // TODO: implement initState
    //设置焦点监听
    _focusNodeUserName.addListener(_focusNodeListener);
    _focusNodePassWord.addListener(_focusNodeListener);
    //监听用户名框的输入改变
    _userNameController.addListener((){
      print(_userNameController.text);
      // 监听文本框输入变化,当有内容的时候,显示尾部清除按钮,否则不显示
      if (_userNameController.text.length > 0) {
        _isShowClear = true;
      }else{
        _isShowClear = false;
      }
      setState(() {
        
      });
    });
    super.initState();
  }
  @override
  void dispose() {
    // TODO: implement dispose
    // 移除焦点监听
    _focusNodeUserName.removeListener(_focusNodeListener);
    _focusNodePassWord.removeListener(_focusNodeListener);
    _userNameController.dispose();
    super.dispose();
  }
  // 监听焦点
  Future _focusNodeListener() async{
    if(_focusNodeUserName.hasFocus){
      print("用户名框获取焦点");
      // 取消密码框的焦点状态
      _focusNodePassWord.unfocus();
    }
    if (_focusNodePassWord.hasFocus) {
      print("密码框获取焦点");
      // 取消用户名框焦点状态
      _focusNodeUserName.unfocus();
    }
  }
  /**
   * 验证用户名
   */
  String validateUserName(value){
    // 正则匹配手机号
    RegExp exp = RegExp(r'^((13[0-9])|(14[0-9])|(15[0-9])|(16[0-9])|(17[0-9])|(18[0-9])|(19[0-9]))\d{8}$');
    if (value.isEmpty) {
      return '用户名不能为空!';
    }else if (!exp.hasMatch(value)) {
      return '请输入正确手机号';
    }
    return null;
  }
  /**
   * 验证密码
   */
  String validatePassWord(value){
    if (value.isEmpty) {
      return '密码不能为空';
    }else if(value.trim().length18){
      return '密码长度不正确';
    }
    return null;
  }
  @override
  Widget build(BuildContext context) {
    ScreenUtil.instance = ScreenUtil(width:750,height:1334)..init(context);
    print(ScreenUtil().scaleHeight);
    // logo 图片区域
    Widget logoImageArea = new Container(
      alignment: Alignment.topCenter,
      // 设置图片为圆形
      child: ClipOval(
        child: Image.asset(
          "images/logo.png",
          height: 100,
          width: 100,
          fit: BoxFit.cover,
        ),
      ),
    );
    
    //输入文本框区域
    Widget inputTextArea = new Container(
      margin: EdgeInsets.only(left: 20,right: 20),
      decoration: new BoxDecoration(
        borderRadius: BorderRadius.all(Radius.circular(8)),
        color: Colors.white
      ),
      child: new Form(
        key: _formKey,
        child: new Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            new TextFormField(
              controller: _userNameController,
              focusNode: _focusNodeUserName,
              //设置键盘类型
              keyboardType: TextInputType.number,
              decoration: InputDecoration(
                labelText: "用户名",
                hintText: "请输入手机号",
                prefixIcon: Icon(Icons.person),
                //尾部添加清除按钮
                suffixIcon:(_isShowClear) 
                          ? IconButton(
                              icon: Icon(Icons.clear),
                              onPressed: (){
                                // 清空输入框内容
                                _userNameController.clear();
                              },
                            ) 
                          : null ,
              ),
              //验证用户名
              validator: validateUserName,
              //保存数据
              onSaved: (String value){
                _username = value;
              },
            ),
            new TextFormField(
              focusNode: _focusNodePassWord,
              decoration: InputDecoration(
                labelText: "密码",
                hintText: "请输入密码",
                prefixIcon: Icon(Icons.lock),
                // 是否显示密码
                suffixIcon: IconButton(
                  icon: Icon((_isShowPwd) ? Icons.visibility : Icons.visibility_off),
                  // 点击改变显示或隐藏密码
                  onPressed: (){
                    setState(() {
                      _isShowPwd = !_isShowPwd;
                    });
                  },
                )
              ),
              obscureText: !_isShowPwd,
              //密码验证
              validator:validatePassWord, 
              //保存数据
              onSaved: (String value){
                _password = value;
              },
            )
          ],
        ),
      ),      
    );
    // 登录按钮区域
    Widget loginButtonArea = new Container(
      margin: EdgeInsets.only(left: 20,right: 20),
      height: 45.0,
      child: new RaisedButton(
        color: Colors.blue[300],
        child: Text(
          "登录",
          style: Theme.of(context).primaryTextTheme.headline,
        ),
        // 设置按钮圆角
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)),
        onPressed: (){
          //点击登录按钮,解除焦点,回收键盘
          _focusNodePassWord.unfocus();
          _focusNodeUserName.unfocus();
          if (_formKey.currentState.validate()) {
            //只有输入通过验证,才会执行这里
            _formKey.currentState.save();
            //todo 登录操作
            print("$_username + $_password");
          }
        },
      ),
    );
    //第三方登录区域
    Widget thirdLoginArea = new Container(
      margin: EdgeInsets.only(left: 20,right: 20),
      child: new Column(
        children: [
          new Row(
            mainAxisSize: MainAxisSize.max,
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              Container(
                width: 80,
                height: 1.0,
                color: Colors.grey,
                
              ),
              Text(
                '第三方登录'
              ),
              Container(
                width: 80,
                height: 1.0,
                color: Colors.grey,
              ),
            ],
          ),
          new SizedBox(
            height: 18,
          ),
          new Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              IconButton(
                color: Colors.green[200],
                // 第三方库icon图标
                icon: Icon(FontAwesomeIcons.weixin),
                iconSize: 40.0,
                onPressed: (){
                },
              ),
              IconButton(
                color: Colors.green[200],
                icon: Icon(FontAwesomeIcons.facebook),
                iconSize: 40.0,
                onPressed: (){
                },
              ),
              IconButton(
                color: Colors.green[200],
                icon: Icon(FontAwesomeIcons.qq),
                iconSize: 40.0,
                onPressed: (){
                },
              )
            ],
          )
        ],
      ),
    );
    //忘记密码  立即注册
    Widget bottomArea = new Container(
      margin: EdgeInsets.only(right: 20,left: 30),
      child: new Row(
        mainAxisSize: MainAxisSize.max,
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          FlatButton(
            child: Text(
              "忘记密码?",
              style: TextStyle(
                color: Colors.blue[400],
                fontSize: 16.0,
              ),
            ),
            //忘记密码按钮,点击执行事件
            onPressed: (){
            },
          ),
          FlatButton(
            child: Text(
              "快速注册",
              style: TextStyle(
                color: Colors.blue[400],
                fontSize: 16.0,
              ),  
            ),
            //点击快速注册、执行事件
            onPressed: (){
            },
          )
        ],
      ),
    );
    return Scaffold(
      backgroundColor: Colors.white,
      // 外层添加一个手势,用于点击空白部分,回收键盘
      body: new GestureDetector(
        onTap: (){
          // 点击空白区域,回收键盘
          print("点击了空白区域");
          _focusNodePassWord.unfocus();
          _focusNodeUserName.unfocus();
        },
        child: new ListView(
          children: [
          new SizedBox(height: ScreenUtil().setHeight(80),),
          logoImageArea,
          new SizedBox(height: ScreenUtil().setHeight(70),),
          inputTextArea,
          new SizedBox(height: ScreenUtil().setHeight(80),),
          loginButtonArea,
          new SizedBox(height: ScreenUtil().setHeight(60),),
          thirdLoginArea,
          new SizedBox(height: ScreenUtil().setHeight(60),),
          bottomArea,
        ],
        ),
      ),
    );
  }
}
---------------------

版权声明:本文为CSDN博主「万里初心」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/ljh910329/article/details/95471566

链接: https://www.fly63.com/article/detial/4677

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!