zoukankan      html  css  js  c++  java
  • Flutter 登录页面

    Flutter 一个漂亮的登录页面

    项目地址:   https://github.com/whiskyma/flutter_demo_login

    flutter-demo-login 快速构建Flutter项目基础模板搭建,并完成登录页制作.

    所需组件如下:

    组件

    名称

    链接

    底部导航切换 bottomNavigationBar https://book.flutterchina.club/chapter5/material_scaffold.html
    抽屉菜单 Drawer https://book.flutterchina.club/chapter5/material_scaffold.html
    Hero动画 Hero https://book.flutterchina.club/chapter9/hero.html
    Loadding动画 flutter_spinkit https://pub.dev/packages/flutter_spinkit
    Toast提示 Toast https://pub.dev/packages/toast
    .... ... ....

    登录页效果图(效验正则,按钮禁用和登录loadding状态显示): 

    设置和注册页:

    各个路由组件:

    main.dart代码如下:

    import 'package:flutter/material.dart';
    import './router/index.dart';
    import 'dart:io';
    import 'package:flutter/services.dart';
    
    void main() {
        runApp(new MyApp());
        if(Platform.isAndroid){ // 设置状态栏背景及颜色
            SystemUiOverlayStyle systemUiOverlayStyle = SystemUiOverlayStyle(statusBarColor: Colors.transparent);
            SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);
        }
    }
    
    class MyApp extends StatelessWidget {
        @override
        Widget build(BuildContext context) {
            return MaterialApp(
                title: '登录Demo',
                debugShowCheckedModeBanner: false,
                routes: routes,
            );
        }
    }

    login.dart代码如下:

    import 'package:flutter/material.dart';
    import '../components/common/toast.dart';
    import '../components/common/loadding.dart';
    
    class Login extends StatefulWidget{
        @override
        _LoginState createState() => new _LoginState();
    }
    
    class _LoginState extends State<Login>{
        // 控制器
        final _unameController =  TextEditingController();
        final _pwdController = TextEditingController();
        final _formKey = GlobalKey<FormState>();
    
        // 焦点
        final focusNode1 = FocusNode();
        final focusNode2 = FocusNode();
    
        bool isEye = true;
        bool isBtnEnabled = false;
        bool showLoading = false;
        final _unameExp = RegExp(r'^(?![0-9]+$)(?![a-z]+$)[0-9a-z]{6,12}$'); //用户名正则
        final _pwdExp = RegExp(r'^(?![0-9]+$)(?![a-z]+$)[0-9a-z]{6,12}$'); //密码正则
    
        // 登录按钮是否可点击
        void checkLoginText(){
            if(_unameExp.hasMatch(_unameController.text)&&_pwdExp.hasMatch(_pwdController.text)){
                this.isBtnEnabled = true;
            }else{
                this.isBtnEnabled = false;
            }
        }
    
        // 登录提交
        void loginSub(){
            FocusScope.of(context).requestFocus(FocusNode()); //收起键盘
            setState((){
                this.showLoading = true;
            });
            loginRequest().then((v) => {
                setState((){
                    this.showLoading = false;
                }),
                // toast提示
                // 模拟登录跳转首页
                ToastCom.show('登录成功', context),
                Navigator.pushNamed(context, '/')
    
                // showDialog(
                //     context: context,
                //     builder: (context){
                //         String alertText = "登录成功!!!"+"
    用户名:"+_unameController.text+"
    密码:"+_pwdController.text;
                //         return AlertDialog(content: Text(alertText));
                //     }
                // )
            });
        }
    
        @override
        void initState(){
            super.initState();
        }
    
        @override
        void dispose(){
            super.dispose();
        }
        
        // 异步操作
        Future loginRequest() async {
            return Future.delayed(Duration(seconds: 3),(){
                print('login success');
            });
        }
    
        @override
        Widget build(BuildContext context){
            List<Widget> childrens = [];
            final _main = Center(
                child: ListView(
                    padding: EdgeInsets.only(left: 30.0, right: 30.0,top: 70.0),
                    children: [
                        Padding(
                            padding: EdgeInsets.only(bottom: 40),
                            child: Hero(
                                tag: 'avatar',
                                child: CircleAvatar(
                                    backgroundColor: Colors.transparent,
                                    radius: 50.0,
                                    child: Image.asset('assets/images/avatar.png'),
                                ),
                            ),
                        ),
                        Form(
                            key: _formKey,
                            autovalidate: true,
                            child: Column(
                                children: [
                                    TextFormField( //用户名
                                        controller: _unameController,
                                        focusNode: focusNode1,//关联focusNode1
                                        keyboardType: TextInputType.text,//键盘类型
                                        maxLength: 12,
                                        textInputAction: TextInputAction.next,//显示'下一步'
                                        decoration: InputDecoration(
                                            hintText: '请输入账号',
                                            labelText: "账号",
                                            contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
                                            prefixIcon:Icon(Icons.perm_identity),
                                            border: OutlineInputBorder(
                                                borderRadius: BorderRadius.circular(40.0) //圆角大小
                                            ),
                                            suffixIcon: _unameController.text.length>0?IconButton(
                                                icon: Icon(
                                                    Icons.clear,
                                                    size: 21,
                                                    color: Color(0xff666666),
                                                ),
                                                onPressed: (){
                                                    setState(() {
                                                        _unameController.text = '';
                                                        checkLoginText();
                                                    });
                                                },
                                            ):null
                                        ),
                                        validator: (v) {
                                            return !_unameExp.hasMatch(v)?'账号由6到12位数字与小写字母组成':null;
                                        },
                                        onEditingComplete: ()=>FocusScope.of(context).requestFocus(focusNode2),
                                        onChanged: (v){
                                            setState(() {
                                                checkLoginText();
                                            });
                                        },
                                    ),
                                    SizedBox(height: 15.0),
                                    TextFormField( //密码
                                        controller: _pwdController,
                                        focusNode: focusNode2,//关联focusNode1
                                        obscureText: isEye, //密码类型 内容用***显示
                                        maxLength: 12,
                                        textInputAction: TextInputAction.done, //显示'完成'
                                        decoration: InputDecoration(
                                            hintText: '请输入密码',
                                            labelText: '密码',
                                            contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
                                            prefixIcon:Icon(Icons.lock),
                                            border: OutlineInputBorder(
                                                borderRadius: BorderRadius.circular(40.0)
                                            ),
                                            suffixIcon: IconButton(
                                                icon: Icon(
                                                    Icons.remove_red_eye,
                                                    size: 21,
                                                    color: Color(0xff666666),
                                                ),
                                                onPressed: (){
                                                    setState(() {
                                                        isEye = !isEye;
                                                    });
                                                },
                                            )
                                        ),
                                        validator:(v){
                                            return !_pwdExp.hasMatch(v)?'密码由6到12位数字与小写字母组成':null;
                                        },
                                        onChanged: (v){
                                            setState(() {
                                                checkLoginText();
                                            });
                                        },
                                        onEditingComplete: ()=>loginSub(), //'完成'回调
                                    )
                                ],
                            ),
                        ),
                        Padding(
                            padding: EdgeInsets.symmetric(vertical: 5.0),
                            child: RaisedButton(
                                color: const Color(0xff2a8fbd),
                                padding: EdgeInsets.symmetric(vertical: 10.0),
                                // splashColor: const Color(0xffde19de),//水波纹颜色
                                disabledColor: const Color(0xff999999),
                                shape:RoundedRectangleBorder(borderRadius: BorderRadius.circular(60.0)),//圆角
                                child: Text('登录',style: TextStyle(fontSize: 18.0, color: Colors.white)),
                                onPressed: !isBtnEnabled?null:loginSub,
                            ),
                        ),
                        FlatButton(
                            child: Text('忘记密码?', style: TextStyle(color: Colors.black54,fontSize: 15.0)),
                            onPressed: () {
                                Navigator.pushNamed(context, 'forget');
                            },
                        ),
                    ],
                ),
            );
    
    
            childrens.add(_main);
            if(this.showLoading){
                childrens.add(Loadding());
            }
            return Scaffold(
                appBar: AppBar(
                    iconTheme: IconThemeData(color: Colors.white),
                    centerTitle: true,
                    title: Text('登录',style: TextStyle(color: Colors.white)),
                ),
                body: Stack(children: childrens),
            );
        }
    }

    项目地址:   https://github.com/whiskyma/flutter_demo_login

    最后,如果大家觉得此项目代码对你点帮助,记得给我点赞哦!!!后续会不断的更新项目代码,继续的完成其他功能!!!
    大家如果遇到什么问题,评论区见!!!
    相互学习,相互进步,记得点赞,谢谢!!!

  • 相关阅读:
    路径
    aspx.cs调用js方法
    计算字符串中每种字母出现的次数
    [转载]获取2个集合List<T>的共同元素
    [转载]行列转换
    [转载]UNION合并查询
    [转载]Case When Then
    [转载]CAST-CONVERT两个函数进行类型转换时的异同点
    [转载]404错误页面设置
    [转载]JQ小知识
  • 原文地址:https://www.cnblogs.com/maqingyuan/p/13637987.html
Copyright © 2011-2022 走看看